From dd768bf1c623521b27d1b16ab50a7b80cbcf8b37 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sun, 18 Feb 2018 09:31:12 +0100 Subject: prog: reorder Minimize arguments Make the predicate the last argument. It's more common and convenient (arguments are not separated by multiple lines). --- pkg/repro/repro.go | 17 +++++++++-------- prog/encoding_test.go | 4 ++-- prog/minimization.go | 2 +- prog/mutation_test.go | 22 +++++++++++----------- prog/prog_test.go | 4 ++-- syz-fuzzer/proc.go | 27 ++++++++++++++------------- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index bbe0e2d7c..fc79f5a8a 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -428,14 +428,15 @@ func (ctx *context) minimizeProg(res *Result) (*Result, error) { if res.Opts.Fault { call = res.Opts.FaultCall } - res.Prog, res.Opts.FaultCall = prog.Minimize(res.Prog, call, func(p1 *prog.Prog, callIndex int) bool { - crashed, err := ctx.testProg(p1, res.Duration, res.Opts) - if err != nil { - ctx.reproLog(0, "minimization failed with %v", err) - return false - } - return crashed - }, true) + res.Prog, res.Opts.FaultCall = prog.Minimize(res.Prog, call, true, + func(p1 *prog.Prog, callIndex int) bool { + crashed, err := ctx.testProg(p1, res.Duration, res.Opts) + if err != nil { + ctx.reproLog(0, "minimization failed with %v", err) + return false + } + return crashed + }) return res, nil } diff --git a/prog/encoding_test.go b/prog/encoding_test.go index da90c6bbe..ffe6f4156 100644 --- a/prog/encoding_test.go +++ b/prog/encoding_test.go @@ -198,10 +198,10 @@ func TestSerializeDeserializeRandom(t *testing.T) { if ok, _, _ := testSerializeDeserialize(t, p0, data0, data1); ok { continue } - p0, _ = Minimize(p0, -1, func(p1 *Prog, _ int) bool { + p0, _ = Minimize(p0, -1, false, func(p1 *Prog, _ int) bool { ok, _, _ := testSerializeDeserialize(t, p1, data0, data1) return !ok - }, false) + }) ok, n0, n1 := testSerializeDeserialize(t, p0, data0, data1) if ok { t.Fatal("flaky?") diff --git a/prog/minimization.go b/prog/minimization.go index 459e6265d..8a77eec03 100644 --- a/prog/minimization.go +++ b/prog/minimization.go @@ -11,7 +11,7 @@ import ( // predicate pred. It iteratively generates simpler programs and asks pred // whether it is equal to the orginal program or not. If it is equivalent then // the simplification attempt is committed and the process continues. -func Minimize(p0 *Prog, callIndex0 int, pred0 func(*Prog, int) bool, crash bool) (*Prog, int) { +func Minimize(p0 *Prog, callIndex0 int, crash bool, pred0 func(*Prog, int) bool) (*Prog, int) { pred := pred0 if debug { pred = func(p *Prog, callIndex int) bool { diff --git a/prog/mutation_test.go b/prog/mutation_test.go index 72f0e3cac..6452eddfa 100644 --- a/prog/mutation_test.go +++ b/prog/mutation_test.go @@ -301,7 +301,7 @@ func TestMinimize(t *testing.T) { if err != nil { t.Fatalf("failed to deserialize original program #%v: %v", ti, err) } - p1, ci := Minimize(p, test.callIndex, test.pred, false) + p1, ci := Minimize(p, test.callIndex, false, test.pred) res := p1.Serialize() if string(res) != test.result { t.Fatalf("minimization produced wrong result #%v\norig:\n%v\nexpect:\n%v\ngot:\n%v\n", @@ -319,21 +319,21 @@ func TestMinimizeRandom(t *testing.T) { iters /= 10 // Long test. for i := 0; i < iters; i++ { p := target.Generate(rs, 5, nil) - Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool { + Minimize(p, len(p.Calls)-1, true, func(p1 *Prog, callIndex int) bool { return false - }, true) - Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool { + }) + Minimize(p, len(p.Calls)-1, true, func(p1 *Prog, callIndex int) bool { return true - }, true) + }) } for i := 0; i < iters; i++ { p := target.Generate(rs, 5, nil) - Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool { + Minimize(p, len(p.Calls)-1, false, func(p1 *Prog, callIndex int) bool { return false - }, false) - Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool { + }) + Minimize(p, len(p.Calls)-1, false, func(p1 *Prog, callIndex int) bool { return true - }, false) + }) } } @@ -343,9 +343,9 @@ func TestMinimizeCallIndex(t *testing.T) { for i := 0; i < iters; i++ { p := target.Generate(rs, 5, nil) ci := r.Intn(len(p.Calls)) - p1, ci1 := Minimize(p, ci, func(p1 *Prog, callIndex int) bool { + p1, ci1 := Minimize(p, ci, r.Intn(2) == 0, func(p1 *Prog, callIndex int) bool { return r.Intn(2) == 0 - }, r.Intn(2) == 0) + }) if ci1 < 0 || ci1 >= len(p1.Calls) || p.Calls[ci].Meta.Name != p1.Calls[ci1].Meta.Name { t.Fatalf("bad call index after minimization") } diff --git a/prog/prog_test.go b/prog/prog_test.go index 4d9baff62..146694f45 100644 --- a/prog/prog_test.go +++ b/prog/prog_test.go @@ -157,9 +157,9 @@ func testCrossTarget(t *testing.T, target *Target, crossTargets []*Target) { testCrossArchProg(t, p, crossTargets) p.Mutate(rs, 20, nil, nil) testCrossArchProg(t, p, crossTargets) - p, _ = Minimize(p, -1, func(*Prog, int) bool { + p, _ = Minimize(p, -1, false, func(*Prog, int) bool { return rs.Int63()%2 == 0 - }, false) + }) testCrossArchProg(t, p, crossTargets) } } diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go index 9653662f3..5d280435b 100644 --- a/syz-fuzzer/proc.go +++ b/syz-fuzzer/proc.go @@ -138,20 +138,21 @@ func (proc *Proc) triageInput(item *WorkTriage) { } } if !item.minimized { - item.p, item.call = prog.Minimize(item.p, item.call, func(p1 *prog.Prog, call1 int) bool { - for i := 0; i < minimizeAttempts; i++ { - info := proc.execute(execOpts, p1, false, false, false, false, true, StatMinimize) - if len(info) == 0 || len(info[call1].Signal) == 0 { - continue // The call was not executed. + item.p, item.call = prog.Minimize(item.p, item.call, false, + func(p1 *prog.Prog, call1 int) bool { + for i := 0; i < minimizeAttempts; i++ { + info := proc.execute(execOpts, p1, false, false, false, false, true, StatMinimize) + if len(info) == 0 || len(info[call1].Signal) == 0 { + continue // The call was not executed. + } + inf := info[call1] + signal := cover.Canonicalize(inf.Signal) + if len(cover.Intersection(newSignal, signal)) == len(newSignal) { + return true + } } - inf := info[call1] - signal := cover.Canonicalize(inf.Signal) - if len(cover.Intersection(newSignal, signal)) == len(newSignal) { - return true - } - } - return false - }, false) + return false + }) } data := item.p.Serialize() -- cgit mrf-deployment