diff --git a/src/internal/fuzz/fuzz.go b/src/internal/fuzz/fuzz.go index 8e0425c0c4..293cb48d4d 100644 --- a/src/internal/fuzz/fuzz.go +++ b/src/internal/fuzz/fuzz.go @@ -18,6 +18,7 @@ import ( "reflect" "runtime" "strings" + "time" ) // CoordinateFuzzing creates several worker processes and communicates with @@ -27,6 +28,9 @@ import ( // with the same arguments as the coordinator, except with the -test.fuzzworker // flag prepended to the argument list. // +// timeout is the amount of wall clock time to spend fuzzing after the corpus +// has loaded. +// // parallel is the number of worker processes to run in parallel. If parallel // is 0, CoordinateFuzzing will run GOMAXPROCS workers. // @@ -43,7 +47,7 @@ import ( // // If a crash occurs, the function will return an error containing information // about the crash, which can be reported to the user. -func CoordinateFuzzing(ctx context.Context, parallel int, seed []CorpusEntry, types []reflect.Type, corpusDir, cacheDir string) (err error) { +func CoordinateFuzzing(ctx context.Context, timeout time.Duration, parallel int, seed []CorpusEntry, types []reflect.Type, corpusDir, cacheDir string) (err error) { if err := ctx.Err(); err != nil { return err } @@ -69,6 +73,12 @@ func CoordinateFuzzing(ctx context.Context, parallel int, seed []CorpusEntry, ty corpus.entries = append(corpus.entries, CorpusEntry{Data: marshalCorpusFile(vals...), Values: vals}) } + if timeout > 0 { + var cancel func() + ctx, cancel = context.WithTimeout(ctx, timeout) + defer cancel() + } + // TODO(jayconrod): do we want to support fuzzing different binaries? dir := "" // same as self binPath := os.Args[0] diff --git a/src/testing/internal/testdeps/deps.go b/src/testing/internal/testdeps/deps.go index 8f587b2e1d..c77aca3da8 100644 --- a/src/testing/internal/testdeps/deps.go +++ b/src/testing/internal/testdeps/deps.go @@ -137,14 +137,9 @@ func (TestDeps) CoordinateFuzzing(timeout time.Duration, parallel int, seed []fu // Fuzzing may be interrupted with a timeout or if the user presses ^C. // In either case, we'll stop worker processes gracefully and save // crashers and interesting values. - ctx, cancel := context.WithCancel(context.Background()) - if timeout > 0 { - ctx, cancel = context.WithTimeout(ctx, timeout) - } - ctx, stop := signal.NotifyContext(ctx, os.Interrupt) - defer stop() + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() - err = fuzz.CoordinateFuzzing(ctx, parallel, seed, types, corpusDir, cacheDir) + err = fuzz.CoordinateFuzzing(ctx, timeout, parallel, seed, types, corpusDir, cacheDir) if err == ctx.Err() { return nil } @@ -158,9 +153,7 @@ func (TestDeps) RunFuzzWorker(fn func(fuzz.CorpusEntry) error) error { // If the worker is interrupted, return quickly and without error. // If only the coordinator process is interrupted, it tells each worker // process to stop by closing its "fuzz_in" pipe. - ctx, cancel := context.WithCancel(context.Background()) - ctx, stop := signal.NotifyContext(ctx, os.Interrupt) - defer stop() + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() err := fuzz.RunFuzzWorker(ctx, fn) if err == ctx.Err() {