aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
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
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')
-rw-r--r--pkg/bisect/bisect.go14
-rw-r--r--pkg/bisect/bisect_test.go6
-rw-r--r--pkg/kconfig/minimize.go36
-rw-r--r--pkg/kconfig/minimize_test.go6
-rw-r--r--pkg/vcs/git.go9
-rw-r--r--pkg/vcs/git_repo_test.go10
-rw-r--r--pkg/vcs/linux.go15
-rw-r--r--pkg/vcs/testos.go6
-rw-r--r--pkg/vcs/vcs.go6
9 files changed, 50 insertions, 58 deletions
diff --git a/pkg/bisect/bisect.go b/pkg/bisect/bisect.go
index 76c518e6c..07f47ccde 100644
--- a/pkg/bisect/bisect.go
+++ b/pkg/bisect/bisect.go
@@ -5,11 +5,10 @@ package bisect
import (
"fmt"
- "io"
- "path/filepath"
"time"
"github.com/google/syzkaller/pkg/build"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/instance"
"github.com/google/syzkaller/pkg/mgrconfig"
@@ -19,11 +18,10 @@ import (
)
type Config struct {
- Trace io.Writer
+ Trace debugtracer.DebugTracer
Fix bool
BinDir string
Ccache string
- DebugDir string
Timeout time.Duration
Kernel KernelConfig
Syzkaller SyzkallerConfig
@@ -540,11 +538,7 @@ func (env *env) processResults(current *vcs.Commit, results []error) (bad, good
}
func (env *env) saveDebugFile(hash string, idx int, data []byte) {
- if env.cfg.DebugDir == "" || len(data) == 0 {
- return
- }
- osutil.MkdirAll(env.cfg.DebugDir)
- osutil.WriteFile(filepath.Join(env.cfg.DebugDir, fmt.Sprintf("%v.%v", hash, idx)), data)
+ env.cfg.Trace.SaveFile(fmt.Sprintf("%v.%v", hash, idx), data)
}
func checkConfig(cfg *Config) error {
@@ -564,5 +558,5 @@ func checkConfig(cfg *Config) error {
}
func (env *env) log(msg string, args ...interface{}) {
- fmt.Fprintf(env.cfg.Trace, msg+"\n", args...)
+ env.cfg.Trace.Log(msg, args...)
}
diff --git a/pkg/bisect/bisect_test.go b/pkg/bisect/bisect_test.go
index db4409a5c..e71903c98 100644
--- a/pkg/bisect/bisect_test.go
+++ b/pkg/bisect/bisect_test.go
@@ -4,13 +4,13 @@
package bisect
import (
- "bytes"
"fmt"
"io/ioutil"
"os"
"strconv"
"testing"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/instance"
"github.com/google/syzkaller/pkg/mgrconfig"
@@ -122,10 +122,9 @@ func runBisection(t *testing.T, baseDir string, test BisectionTest) (*Result, er
if err != nil {
t.Fatal(err)
}
- trace := new(bytes.Buffer)
cfg := &Config{
Fix: test.fix,
- Trace: trace,
+ Trace: &debugtracer.TestTracer{T: t},
Manager: &mgrconfig.Config{
Derived: mgrconfig.Derived{
TargetOS: targets.TestOS,
@@ -147,7 +146,6 @@ func runBisection(t *testing.T, baseDir string, test BisectionTest) (*Result, er
test: test,
}
res, err := runImpl(cfg, r, inst)
- t.Log(trace.String())
return res, err
}
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)
}
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go
index 1a90341ac..163f3e497 100644
--- a/pkg/vcs/git.go
+++ b/pkg/vcs/git.go
@@ -7,7 +7,6 @@ import (
"bufio"
"bytes"
"fmt"
- "io"
"net/mail"
"os"
"os/exec"
@@ -16,6 +15,7 @@ import (
"strings"
"time"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
@@ -431,7 +431,8 @@ func splitEmail(email string) (user, domain string, err error) {
return
}
-func (git *git) Bisect(bad, good string, trace io.Writer, pred func() (BisectResult, error)) ([]*Commit, error) {
+func (git *git) Bisect(bad, good string, dt debugtracer.DebugTracer, pred func() (BisectResult,
+ error)) ([]*Commit, error) {
git.reset()
firstBad, err := git.getCommit(bad)
if err != nil {
@@ -442,7 +443,7 @@ func (git *git) Bisect(bad, good string, trace io.Writer, pred func() (BisectRes
return nil, err
}
defer git.reset()
- fmt.Fprintf(trace, "# git bisect start %v %v\n%s", bad, good, output)
+ dt.Log("# git bisect start %v %v\n%s", bad, good, output)
current, err := git.HeadCommit()
if err != nil {
return nil, err
@@ -463,7 +464,7 @@ func (git *git) Bisect(bad, good string, trace io.Writer, pred func() (BisectRes
firstBad = current
}
output, err = git.git("bisect", bisectTerms[res])
- fmt.Fprintf(trace, "# git bisect %v %v\n%s", bisectTerms[res], current.Hash, output)
+ dt.Log("# git bisect %v %v\n%s", bisectTerms[res], current.Hash, output)
if err != nil {
if bytes.Contains(output, []byte("There are only 'skip'ped commits left to test")) {
return git.bisectInconclusive(output)
diff --git a/pkg/vcs/git_repo_test.go b/pkg/vcs/git_repo_test.go
index a2610315f..9a044e870 100644
--- a/pkg/vcs/git_repo_test.go
+++ b/pkg/vcs/git_repo_test.go
@@ -12,6 +12,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/google/syzkaller/pkg/debugtracer"
)
func init() {
@@ -378,7 +379,7 @@ func TestBisect(t *testing.T) {
}
for i, test := range tests {
t.Logf("TEST %v", i)
- result, err := repo.repo.Bisect(commits[4], commits[0], (*testWriter)(t), test.pred)
+ result, err := repo.repo.Bisect(commits[4], commits[0], &debugtracer.TestTracer{T: t}, test.pred)
if err != nil {
t.Fatal(err)
}
@@ -394,10 +395,3 @@ func TestBisect(t *testing.T) {
}
}
}
-
-type testWriter testing.T
-
-func (t *testWriter) Write(data []byte) (int, error) {
- (*testing.T)(t).Log(string(data))
- return len(data), nil
-}
diff --git a/pkg/vcs/linux.go b/pkg/vcs/linux.go
index a99215528..93c9ca045 100644
--- a/pkg/vcs/linux.go
+++ b/pkg/vcs/linux.go
@@ -6,7 +6,6 @@ package vcs
import (
"bytes"
"fmt"
- "io"
"net/mail"
"path/filepath"
"regexp"
@@ -15,6 +14,7 @@ import (
"strings"
"time"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/pkg/kconfig"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/prog"
@@ -237,8 +237,9 @@ func linuxAlterConfigs(cf *kconfig.ConfigFile, tags map[string]bool) {
}
}
-func (ctx *linux) Bisect(bad, good string, trace io.Writer, pred func() (BisectResult, error)) ([]*Commit, error) {
- commits, err := ctx.git.Bisect(bad, good, trace, pred)
+func (ctx *linux) Bisect(bad, good string, dt debugtracer.DebugTracer, pred func() (BisectResult,
+ error)) ([]*Commit, error) {
+ commits, err := ctx.git.Bisect(bad, good, dt, pred)
if len(commits) == 1 {
ctx.addMaintainers(commits[0])
}
@@ -309,10 +310,10 @@ func ParseMaintainersLinux(text []byte) Recipients {
const configBisectTag = "# Minimized by syzkaller"
-func (ctx *linux) Minimize(target *targets.Target, original, baseline []byte, trace io.Writer,
- pred func(test []byte) (BisectResult, error)) ([]byte, error) {
+func (ctx *linux) Minimize(target *targets.Target, original, baseline []byte,
+ dt debugtracer.DebugTracer, pred func(test []byte) (BisectResult, error)) ([]byte, error) {
if bytes.HasPrefix(original, []byte(configBisectTag)) {
- fmt.Fprintf(trace, "# configuration already minimized\n")
+ dt.Log("# configuration already minimized\n")
return original, nil
}
kconf, err := kconfig.Parse(target, filepath.Join(ctx.git.dir, "Kconfig"))
@@ -333,7 +334,7 @@ func (ctx *linux) Minimize(target *targets.Target, original, baseline []byte, tr
res, err := pred(serialize(candidate))
return res == BisectBad, err
}
- minConfig, err := kconf.Minimize(baselineConfig, originalConfig, kconfPred, trace)
+ minConfig, err := kconf.Minimize(baselineConfig, originalConfig, kconfPred, dt)
if err != nil {
return nil, err
}
diff --git a/pkg/vcs/testos.go b/pkg/vcs/testos.go
index fa9f7cc9b..c9acf1781 100644
--- a/pkg/vcs/testos.go
+++ b/pkg/vcs/testos.go
@@ -5,8 +5,8 @@ package vcs
import (
"fmt"
- "io"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/sys/targets"
)
@@ -30,8 +30,8 @@ func (ctx *testos) EnvForCommit(binDir, commit string, kernelConfig []byte) (*Bi
return &BisectEnv{KernelConfig: kernelConfig}, nil
}
-func (ctx *testos) Minimize(target *targets.Target, original, baseline []byte, trace io.Writer,
- pred func(test []byte) (BisectResult, error)) ([]byte, error) {
+func (ctx *testos) Minimize(target *targets.Target, original, baseline []byte,
+ dt debugtracer.DebugTracer, pred func(test []byte) (BisectResult, error)) ([]byte, error) {
if res, err := pred(baseline); err != nil {
return nil, err
} else if res == BisectBad {
diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go
index acdb9837e..7ede983f6 100644
--- a/pkg/vcs/vcs.go
+++ b/pkg/vcs/vcs.go
@@ -7,7 +7,6 @@ package vcs
import (
"bytes"
"fmt"
- "io"
"net/mail"
"regexp"
"sort"
@@ -15,6 +14,7 @@ import (
"time"
"github.com/google/syzkaller/dashboard/dashapi"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/sys/targets"
)
@@ -116,7 +116,7 @@ type Bisecter interface {
// Progress of the process is streamed to the provided trace.
// Returns the first commit on which the predicate returns BisectBad,
// or multiple commits if bisection is inconclusive due to BisectSkip.
- Bisect(bad, good string, trace io.Writer, pred func() (BisectResult, error)) ([]*Commit, error)
+ Bisect(bad, good string, dt debugtracer.DebugTracer, pred func() (BisectResult, error)) ([]*Commit, error)
// PreviousReleaseTags returns list of preceding release tags that are reachable from the given commit.
// If the commit itself has a release tag, this tag is not included.
@@ -128,7 +128,7 @@ type Bisecter interface {
}
type ConfigMinimizer interface {
- Minimize(target *targets.Target, original, baseline []byte, trace io.Writer,
+ Minimize(target *targets.Target, original, baseline []byte, dt debugtracer.DebugTracer,
pred func(test []byte) (BisectResult, error)) ([]byte, error)
}