"reflect"
"runtime"
"strings"
+ "time"
)
// CoordinateFuzzing creates several worker processes and communicates with
// 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.
//
//
// 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
}
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]
// 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
}
// 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() {