diff options
| author | Jouni Hogander <jouni.hogander@unikie.com> | 2020-11-10 15:01:26 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-12-10 12:57:35 +0100 |
| commit | cbdf514ebdff5b19bc93cdfcc81598587627330e (patch) | |
| tree | cec672b32afba297ff06bc3cd4d39205596cc78a /pkg/kconfig | |
| parent | f86bec81e1bafa82d30486258de616fff295b5f7 (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.go | 36 | ||||
| -rw-r--r-- | pkg/kconfig/minimize_test.go | 6 |
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) } |
