forked from dvyukov/go-fuzz
/
main.go
96 lines (85 loc) · 2.83 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2015 Dmitry Vyukov. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package main
import (
"flag"
"log"
"net"
"os"
"os/signal"
"runtime"
"runtime/debug"
"sync/atomic"
"syscall"
"time"
)
//go:generate go build github.com/dvyukov/go-fuzz/go-fuzz/vendor/github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs
//go:generate ./go-bindata-assetfs assets/...
//go:generate rm go-bindata-assetfs
var (
flagWorkdir = flag.String("workdir", "", "dir with persistent work data")
flagProcs = flag.Int("procs", runtime.NumCPU(), "parallelism level")
flagTimeout = flag.Int("timeout", 10, "test timeout, in seconds")
flagMinimize = flag.Duration("minimize", 1*time.Minute, "time limit for input minimization")
flagMaster = flag.String("master", "", "master mode (value is master address)")
flagSlave = flag.String("slave", "", "slave mode (value is master address)")
flagBin = flag.String("bin", "", "test binary built with go-fuzz-build")
flagDumpCover = flag.Bool("dumpcover", false, "dump coverage profile into workdir")
flagDup = flag.Bool("dup", false, "collect duplicate crashers")
flagTestOutput = flag.Bool("testoutput", false, "print test binary output to stdout (for debugging only)")
flagCoverCounters = flag.Bool("covercounters", true, "use coverage hit counters")
flagSonar = flag.Bool("sonar", true, "use sonar hints")
flagV = flag.Int("v", 0, "verbosity level")
flagHTTP = flag.String("http", "", "HTTP server listen address (master mode only)")
shutdown uint32
shutdownC = make(chan struct{})
shutdownCleanup []func()
)
func main() {
flag.Parse()
if *flagMaster != "" && *flagSlave != "" {
log.Fatalf("both -master and -slave are specified")
}
if *flagHTTP != "" && *flagSlave != "" {
log.Fatalf("both -http and -slave are specified")
}
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT)
<-c
atomic.StoreUint32(&shutdown, 1)
close(shutdownC)
log.Printf("shutting down...")
time.Sleep(2 * time.Second)
for _, f := range shutdownCleanup {
f()
}
os.Exit(0)
}()
runtime.GOMAXPROCS(min(*flagProcs, runtime.NumCPU()))
debug.SetGCPercent(50) // most memory is in large binary blobs
lowerProcessPrio()
if *flagMaster != "" || *flagSlave == "" {
if *flagWorkdir == "" {
log.Fatalf("-workdir is not set")
}
if *flagMaster == "" {
*flagMaster = "localhost:0"
}
ln, err := net.Listen("tcp", *flagMaster)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
if *flagMaster == "localhost:0" && *flagSlave == "" {
*flagSlave = ln.Addr().String()
}
go masterMain(ln)
}
if *flagSlave != "" {
if *flagBin == "" {
log.Fatalf("-bin is not set")
}
go slaveMain()
}
select {}
}