aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/kconfig
diff options
context:
space:
mode:
authorJouni Hogander <jouni.hogander@unikie.com>2020-11-10 15:01:26 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-12-10 12:57:35 +0100
commitcbdf514ebdff5b19bc93cdfcc81598587627330e (patch)
treecec672b32afba297ff06bc3cd4d39205596cc78a /pkg/kconfig
parentf86bec81e1bafa82d30486258de616fff295b5f7 (diff)
pkg/kconfig: store minimization results
Store config options identified using DebugTracer. Also change bisection and configuration minimization code to use new DebugTracer.
Diffstat (limited to 'pkg/kconfig')
-rw-r--r--pkg/kconfig/minimize.go36
-rw-r--r--pkg/kconfig/minimize_test.go6
2 files changed, 23 insertions, 19 deletions
diff --git a/pkg/kconfig/minimize.go b/pkg/kconfig/minimize.go
index bbcb95414..bbc66c4c1 100644
--- a/pkg/kconfig/minimize.go
+++ b/pkg/kconfig/minimize.go
@@ -4,9 +4,10 @@
package kconfig
import (
- "fmt"
- "io"
"sort"
+
+ "github.com/google/syzkaller/pkg/debugtracer"
+ "github.com/google/syzkaller/pkg/osutil"
)
// Minimize finds an equivalent with respect to the provided predicate, but smaller config.
@@ -15,15 +16,14 @@ import (
// mostly by adding more configs. The minimization procedure thus consists of figuring out what set of configs that
// are present in full and are not present in base affect the predicate.
func (kconf *KConfig) Minimize(base, full *ConfigFile, pred func(*ConfigFile) (bool, error),
- tw io.Writer) (*ConfigFile, error) {
- trace := traceLogger{tw}
+ dt debugtracer.DebugTracer) (*ConfigFile, error) {
diff, other := kconf.missingConfigs(base, full)
- trace.log("kconfig minimization: base=%v full=%v diff=%v", len(base.Configs), len(full.Configs), len(diff))
+ dt.Log("kconfig minimization: base=%v full=%v diff=%v", len(base.Configs), len(full.Configs), len(diff))
// First, check the base config as is, it is the smallest we can possibly get.
if res, err := pred(base); err != nil {
return nil, err
} else if res {
- trace.log("base config crashes")
+ dt.Log("base config crashes")
return base, nil
}
// Since base does not crash, full config is our best bet for now.
@@ -45,7 +45,7 @@ top:
for len(diff) >= 2 {
half := len(diff) / 2
for _, part := range [][]string{diff[:half], diff[half:]} {
- trace.log("trying half: %v", part)
+ dt.Log("trying half: %v", part)
closure := kconf.addDependencies(base, full, part)
candidate := base.clone()
// Always move all non-tristate configs from full to base as we don't minimize them.
@@ -60,20 +60,21 @@ top:
return nil, err
}
if res {
- trace.log("half crashed")
+ dt.Log("half crashed")
diff = part
current = candidate
suspects = closure
continue top
}
}
- trace.log("both halves did not crash")
+ dt.Log("both halves did not crash")
break
}
if suspects != nil {
- trace.log("resulting configs: %v", suspects)
+ dt.Log("resulting configs: %v", suspects)
+ kconf.writeSuspects(dt, suspects)
} else {
- trace.log("only full config crashes")
+ dt.Log("only full config crashes")
}
return current, nil
}
@@ -110,10 +111,15 @@ func (kconf *KConfig) addDependencies(base, full *ConfigFile, configs []string)
return sorted
}
-type traceLogger struct{ io.Writer }
+const CauseConfigFile = "cause.config"
+
+func (kconf *KConfig) writeSuspects(dt debugtracer.DebugTracer, suspects []string) {
+ cf := &ConfigFile{
+ Map: make(map[string]*Config),
+ }
-func (trace traceLogger) log(msg string, args ...interface{}) {
- if trace.Writer != nil {
- fmt.Fprintf(trace.Writer, msg+"\n", args...)
+ for _, cfg := range suspects {
+ cf.Set(cfg, Yes)
}
+ osutil.WriteFile(CauseConfigFile, cf.Serialize())
}
diff --git a/pkg/kconfig/minimize_test.go b/pkg/kconfig/minimize_test.go
index 28dca33bd..1e1d2b0f2 100644
--- a/pkg/kconfig/minimize_test.go
+++ b/pkg/kconfig/minimize_test.go
@@ -4,10 +4,10 @@
package kconfig
import (
- "bytes"
"fmt"
"testing"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/sys/targets"
)
@@ -106,9 +106,7 @@ CONFIG_ROSE=y
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
- trace := new(bytes.Buffer)
- res, err := kconf.Minimize(base, full, test.pred, trace)
- t.Log(trace.String())
+ res, err := kconf.Minimize(base, full, test.pred, &debugtracer.TestTracer{T: t})
if err != nil {
t.Fatal(err)
}