aboutsummaryrefslogtreecommitdiff
path: root/src/internal/fuzz/fuzz.go
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2020-12-17 17:25:42 -0500
committerJay Conrod <jayconrod@google.com>2020-12-23 16:33:50 +0000
commita1646595e63cc0bf7f566bb9b657f826cbda22a1 (patch)
tree56f50513d0ee0e56fda0125cd38c72bc12ded09a /src/internal/fuzz/fuzz.go
parent3ea342eb2e2f65a02bc84e206a4e7615747df49a (diff)
downloadgo-a1646595e63cc0bf7f566bb9b657f826cbda22a1.tar.xz
[dev.fuzz] cmd/go: implement -fuzztime flag and support cancellation
fuzz.CoordinateFuzzing and RunFuzzWorker now accept a context.Context parameter. They should terminate gracefully when the context is cancelled. The worker should exit quickly without processing more inputs. The coordinator should save interesting inputs to the cache. The testing package can't import context directly, so it provides a timeout argument to testdeps.CoordinateFuzzing instead. The testdeps wrapper sets the timeout and installs an interrupt handler (for SIGINT on POSIX and the equivalent on Windows) that cancels the context when ^C is pressed. Note that on POSIX platforms, pressing ^C causes the shell to deliver SIGINT to all processes in the active group: so 'go test', the coordinator, and the workers should all react to that. On Windows, pressing ^C only interrupts 'go test'. We may want to look at that separately. Change-Id: I924d3be2905f9685dae82ff3c047ca3d6b5e2357 Reviewed-on: https://go-review.googlesource.com/c/go/+/279487 Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> Trust: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src/internal/fuzz/fuzz.go')
-rw-r--r--src/internal/fuzz/fuzz.go35
1 files changed, 18 insertions, 17 deletions
diff --git a/src/internal/fuzz/fuzz.go b/src/internal/fuzz/fuzz.go
index 2ab16b1189..aacc053682 100644
--- a/src/internal/fuzz/fuzz.go
+++ b/src/internal/fuzz/fuzz.go
@@ -8,6 +8,7 @@
package fuzz
import (
+ "context"
"crypto/sha256"
"fmt"
"io/ioutil"
@@ -15,7 +16,6 @@ import (
"path/filepath"
"runtime"
"sync"
- "time"
)
// CoordinateFuzzing creates several worker processes and communicates with
@@ -39,14 +39,13 @@ 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(parallel int, seed [][]byte, corpusDir, cacheDir string) (err error) {
+func CoordinateFuzzing(ctx context.Context, parallel int, seed [][]byte, corpusDir, cacheDir string) (err error) {
+ if err := ctx.Err(); err != nil {
+ return err
+ }
if parallel == 0 {
parallel = runtime.GOMAXPROCS(0)
}
- // TODO(jayconrod): support fuzzing indefinitely or with a given duration.
- // The value below is just a placeholder until we figure out how to handle
- // interrupts.
- duration := 5 * time.Second
corpus, err := readCorpusAndCache(seed, corpusDir, cacheDir)
if err != nil {
@@ -121,26 +120,28 @@ func CoordinateFuzzing(parallel int, seed [][]byte, corpusDir, cacheDir string)
defer func() {
close(c.doneC)
wg.Wait()
- if err == nil {
- for _, err = range workerErrs {
- if err != nil {
- // Return the first error found.
- return
+ if err == nil || err == ctx.Err() {
+ for _, werr := range workerErrs {
+ if werr != nil {
+ // Return the first error found, replacing ctx.Err() if a more
+ // interesting error is found.
+ err = werr
}
}
}
}()
// Main event loop.
- stopC := time.After(duration)
i := 0
for {
select {
- // TODO(jayconrod): handle interruptions like SIGINT.
-
- case <-stopC:
- // Time's up.
- return nil
+ case <-ctx.Done():
+ // Interrupted, cancelled, or timed out.
+ // TODO(jayconrod,katiehockman): On Windows, ^C only interrupts 'go test',
+ // not the coordinator or worker processes. 'go test' will stop running
+ // actions, but it won't interrupt its child processes. This makes it
+ // difficult to stop fuzzing on Windows without a timeout.
+ return ctx.Err()
case crasher := <-c.crasherC:
// A worker found a crasher. Write it to testdata and return it.