Skip to content

Commit ef2ebbe

Browse files
committed
internal/fuzz: log that minimization is occurring
Previously, when fuzzing for a period of time, the command line output would look something like this: fuzz: minimizing 34995-byte crash input... fuzz: elapsed: 3s, execs: 13821 (4604/sec), new interesting: 0 (total: 1) fuzz: elapsed: 6s, execs: 13821 (2303/sec), new interesting: 0 (total: 1) fuzz: elapsed: 9s, execs: 13821 (1535/sec), new interesting: 0 (total: 1) --- FAIL: FuzzFoo (9.05s) This is the same output it has while fuzzing, so if minimization runs for a long time (default allows 1 minute), then it looks like minimization is hanging. It's also confusing that the execs/sec would continually decrease. Now, when minimization is running, the command line output will look something like this: fuzz: minimizing 34995-byte crash input... fuzz: elapsed: 3s, minimizing fuzz: elapsed: 6s, minimizing fuzz: elapsed: 9s, minimizing fuzz: elapsed: 9s, minimizing --- FAIL: FuzzFoo (9.05s) The final "fuzz: elapsed: 6s, minimizing" could be printed twice because we always print one final log to the command line before we exit. Updates golang#48820 Change-Id: Ie5b9fde48b8d4e36e13a81ae50a6d69bf4d0dbe3 Reviewed-on: https://go-review.googlesource.com/c/go/+/354371 Trust: Katie Hockman <katie@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
1 parent 0f52292 commit ef2ebbe

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/cmd/go/testdata/script/test_fuzz_minimize.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ stdout FAIL
7474
# Test that re-running the unminimized value causes a crash.
7575
! go test -run=FuzzMinimizerRecoverable minimizer_test.go
7676

77+
! go test -fuzz=FuzzMinimizerTooSlow -run=FuzzMinimizerTooSlow -fuzzminimizetime=3s minimizer_test.go
78+
stdout 'fuzz: minimizing'
79+
stdout 'fuzz: elapsed: 3s, minimizing'
80+
stdout 'testdata[/\\]fuzz[/\\]FuzzMinimizerTooSlow[/\\]'
81+
stdout FAIL
82+
7783
# TODO(jayconrod,katiehockman): add a test which verifies that the right bytes
7884
# are written to testdata in the case of an interrupt during minimization.
7985

@@ -87,6 +93,7 @@ package fuzz_test
8793
import (
8894
"os"
8995
"testing"
96+
"time"
9097
)
9198

9299
func FuzzMinimizeZeroDurationSet(f *testing.F) {
@@ -142,6 +149,16 @@ func FuzzMinimizerNonrecoverable(f *testing.F) {
142149
}
143150
})
144151
}
152+
153+
func FuzzMinimizerTooSlow(f *testing.F) {
154+
f.Fuzz(func(t *testing.T, b []byte) {
155+
if len(b) > 50 {
156+
t.Error("error here")
157+
time.Sleep(2 * time.Second)
158+
}
159+
})
160+
}
161+
145162
-- check_testdata.go --
146163
// +build ignore
147164

src/internal/fuzz/fuzz.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,21 +136,20 @@ func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err err
136136

137137
// Ensure that any crash we find is written to the corpus, even if an error
138138
// or interruption occurs while minimizing it.
139-
var crashMinimizing *fuzzResult
140139
crashWritten := false
141140
defer func() {
142-
if crashMinimizing == nil || crashWritten {
141+
if c.crashMinimizing == nil || crashWritten {
143142
return
144143
}
145-
fileName, werr := writeToCorpus(crashMinimizing.entry.Data, opts.CorpusDir)
144+
fileName, werr := writeToCorpus(c.crashMinimizing.entry.Data, opts.CorpusDir)
146145
if werr != nil {
147146
err = fmt.Errorf("%w\n%v", err, werr)
148147
return
149148
}
150149
if err == nil {
151150
err = &crashError{
152151
name: filepath.Base(fileName),
153-
err: errors.New(crashMinimizing.crasherMsg),
152+
err: errors.New(c.crashMinimizing.crasherMsg),
154153
}
155154
}
156155
}()
@@ -198,7 +197,7 @@ func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err err
198197
for {
199198
var inputC chan fuzzInput
200199
input, ok := c.peekInput()
201-
if ok && crashMinimizing == nil && !stopping {
200+
if ok && c.crashMinimizing == nil && !stopping {
202201
inputC = c.inputC
203202
}
204203

@@ -236,15 +235,15 @@ func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err err
236235
break
237236
}
238237
if c.canMinimize() && result.canMinimize {
239-
if crashMinimizing != nil {
238+
if c.crashMinimizing != nil {
240239
// This crash is not minimized, and another crash is being minimized.
241240
// Ignore this one and wait for the other one to finish.
242241
break
243242
}
244243
// Found a crasher but haven't yet attempted to minimize it.
245244
// Send it back to a worker for minimization. Disable inputC so
246245
// other workers don't continue fuzzing.
247-
crashMinimizing = &result
246+
c.crashMinimizing = &result
248247
fmt.Fprintf(c.opts.Log, "fuzz: minimizing %d-byte crash input...\n", len(result.entry.Data))
249248
c.queueForMinimization(result, nil)
250249
} else if !crashWritten {
@@ -308,7 +307,7 @@ func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err err
308307
// number of new edges that this result expanded.
309308
// TODO(jayconrod, katiehockman): Don't write a value that's already
310309
// in the corpus.
311-
if c.canMinimize() && result.canMinimize && crashMinimizing == nil {
310+
if c.canMinimize() && result.canMinimize && c.crashMinimizing == nil {
312311
// Send back to workers to find a smaller value that preserves
313312
// at least one new coverage bit.
314313
c.queueForMinimization(result, keepCoverage)
@@ -604,6 +603,9 @@ type coordinator struct {
604603
// same thing.
605604
minimizeQueue queue
606605

606+
// crashMinimizing is the crash that is currently being minimized.
607+
crashMinimizing *fuzzResult
608+
607609
// coverageMask aggregates coverage that was found for all inputs in the
608610
// corpus. Each byte represents a single basic execution block. Each set bit
609611
// within the byte indicates that an input has triggered that block at least
@@ -692,6 +694,8 @@ func (c *coordinator) logStats() {
692694
} else {
693695
fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, testing seed corpus: %d/%d completed\n", c.elapsed(), runSoFar, c.warmupInputCount)
694696
}
697+
} else if c.crashMinimizing != nil {
698+
fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, minimizing\n", c.elapsed())
695699
} else {
696700
rate := float64(c.count-c.countLastLog) / now.Sub(c.timeLastLog).Seconds()
697701
if coverageEnabled {

0 commit comments

Comments
 (0)