Git Product home page Git Product logo

go-fuzz's Introduction

go-fuzz: randomized testing for Go

Go-fuzz is a coverage-guided fuzzing solution for testing of Go packages. Fuzzing is mainly applicable to packages that parse complex inputs (both text and binary), and is especially useful for hardening of systems that parse inputs from potentially malicious users (e.g. anything accepted over a network).

Note: go-fuzz has recently added preliminary support for fuzzing Go Modules. See the section below for more details. If you encounter a problem with modules, please file an issue with details. A workaround might be to disable modules via export GO111MODULE=off.

Usage

First, you need to write a test function of the form:

func Fuzz(data []byte) int

Data is a random input generated by go-fuzz, note that in most cases it is invalid. The function must return 1 if the fuzzer should increase priority of the given input during subsequent fuzzing (for example, the input is lexically correct and was parsed successfully); -1 if the input must not be added to corpus even if gives new coverage; and 0 otherwise; other values are reserved for future use.

The Fuzz function must be in a package that go-fuzz can import. This means the code you want to test can't be in package main. Fuzzing internal packages is supported, however.

In its basic form the Fuzz function just parses the input, and go-fuzz ensures that it does not panic, crash the program, allocate insane amount of memory nor hang. Fuzz function can also do application-level checks, which will make testing more efficient (discover more bugs). For example, Fuzz function can serialize all inputs that were successfully deserialized, thus ensuring that serialization can handle everything deserialization can produce. Or, Fuzz function can deserialize-serialize-deserialize-serialize and check that results of first and second serialization are equal. Or, Fuzz function can feed the input into two different implementations (e.g. dumb and optimized) and check that the output is equal. To communicate application-level bugs Fuzz function should panic (os.Exit(1) will work too, but panic message contains more info). Note that Fuzz function should not output to stdout/stderr, it will slow down fuzzing and nobody will see the output anyway. The exception is printing info about a bug just before panicking.

Here is an example of a simple Fuzz function for image/png package:

package png

import (
	"bytes"
	"image/png"
)

func Fuzz(data []byte) int {
	png.Decode(bytes.NewReader(data))
	return 0
}

A more useful Fuzz function would look like:

func Fuzz(data []byte) int {
	img, err := png.Decode(bytes.NewReader(data))
	if err != nil {
		if img != nil {
			panic("img != nil on error")
		}
		return 0
	}
	var w bytes.Buffer
	err = png.Encode(&w, img)
	if err != nil {
		panic(err)
	}
	return 1
}

The second step is collection of initial input corpus. Ideally, files in the corpus are as small as possible and as diverse as possible. You can use inputs used by unit tests and/or generate them. For example, for an image decoding package you can encode several small bitmaps (black, random noise, white with few non-white pixels) with different levels of compressions and use that as the initial corpus. Go-fuzz will deduplicate and minimize the inputs. So throwing in a thousand of inputs is fine, diversity is more important.

Put the initial corpus into the workdir/corpus directory (in our case examples/png/corpus). Go-fuzz will add own inputs to the corpus directory. Consider committing the generated inputs to your source control system, this will allow you to restart go-fuzz without losing previous work.

The go-fuzz-corpus repository contains a bunch of examples of test functions and initial input corpuses for various packages.

The next step is to get go-fuzz:

$ go install github.com/dvyukov/go-fuzz/go-fuzz@latest github.com/dvyukov/go-fuzz/go-fuzz-build@latest

Then, download the corpus and build the test program with necessary instrumentation:

$ git clone https://github.com/dvyukov/go-fuzz-corpus.git
$ cd go-fuzz-corpus
$ cd png
$ go-fuzz-build

This will produce png-fuzz.zip archive.

Now we are ready to go:

$ go-fuzz

Go-fuzz will generate and test various inputs in an infinite loop. Workdir is used to store persistent data like current corpus and crashers, it allows fuzzer to continue after restart. Discovered bad inputs are stored in workdir/crashers dir; where file without a suffix contains binary input, file with .quoted suffix contains quoted input that can be directly copied into a reproducer program or a test, file with .output suffix contains output of the test on this input. Every few seconds go-fuzz prints logs to stderr of the form:

2015/04/25 12:39:53 workers: 500, corpus: 186 (42s ago), crashers: 3,
     restarts: 1/8027, execs: 12009519 (121224/sec), cover: 2746, uptime: 1m39s

Where workers means number of tests running in parallel (set with -procs flag). corpus is current number of interesting inputs the fuzzer has discovered, time in brackets says when the last interesting input was discovered. crashers is number of discovered bugs (check out workdir/crashers dir). restarts is the rate with which the fuzzer restarts test processes. The rate should be close to 1/10000 (which is the planned restart rate); if it is considerably higher than 1/10000, consider fixing already discovered bugs which lead to frequent restarts. execs is total number of test executions, and the number in brackets is the average speed of test executions. cover is number of bits set in a hashed coverage bitmap, if this number grows fuzzer uncovers new lines of code; size of the bitmap is 64K; ideally cover value should be less than ~5000, otherwise fuzzer can miss new interesting inputs due to hash collisions. And finally uptime is uptime of the process. This same information is also served via http (see the -http flag).

Modules support

go-fuzz has preliminary support for fuzzing Go Modules. go-fuzz respects the standard GO111MODULE environment variable, which can be set to on, off, or auto.

go-fuzz-build will add a require for github.com/dvyukov/go-fuzz to your go.mod. If desired, you may remove this once the build is complete.

Vendoring with modules is not yet supported. A vendor directory will be ignored, and go-fuzz will report an error if GOFLAGS=-mod=vendor is set.

Note that while modules are used to prepare the build, the final instrumented build is still done in GOPATH mode. For most modules, this should not matter.

libFuzzer support

go-fuzz-build can also generate an archive file that can be used with libFuzzer instead of go-fuzz (requires linux).

Sample usage:

$ cd $GOPATH/src/github.com/dvyukov/go-fuzz-corpus/fmt
$ go-fuzz-build -libfuzzer  # produces fmt.a
$ clang -fsanitize=fuzzer fmt.a -o fmt.libfuzzer
$ ./fmt.libfuzzer

When run with -libfuzzer, go-fuzz-build adds the additional build tag gofuzz_libfuzzer when building code.

Continuous Fuzzing

Just as unit-testing, fuzzing is better done continuously.

Currently there are 2 services that offer continuous fuzzing based on go-fuzz:

Random Notes

go-fuzz-build builds the program with gofuzz build tag, this allows to put the Fuzz function implementation directly into the tested package, but exclude it from normal builds with // +build gofuzz directive.

If your inputs contain a checksum, it can make sense to append/update the checksum in the Fuzz function. The chances that go-fuzz will generate the correct checksum are very low, so most work will be in vain otherwise.

Go-fuzz can utilize several machines. To do this, start the coordinator process separately:

$ go-fuzz -workdir=examples/png -coordinator=127.0.0.1:8745

It will manage persistent corpus and crashers and coordinate work of worker processes. Then run one or more worker processes as:

$ go-fuzz -bin=./png-fuzz.zip -worker=127.0.0.1:8745 -procs=10

External Articles

History rewrite

go-fuzz repository history was recently rewritten to exclude examples directory to reduce total repository size and download time (see #88, #114 and https://github.com/dvyukov/go-fuzz-corpus). Unfortunately, that means that go get -u command will fail if you had a previous version installed. Please remove $GOPATH/github.com/dvyukov/go-fuzz before running go get again.

Credits and technical details

Go-fuzz fuzzing logic is heavily based on american fuzzy lop, so refer to AFL readme if you are interested in technical details. AFL is written and maintained by Michal Zalewski. Some of the mutations employed by go-fuzz are inspired by work done by Mateusz Jurczyk, Gynvael Coldwind and Felix Gröbert.

Trophies

If you find some bugs with go-fuzz and are comfortable with sharing them, I would like to add them to this list. Please either send a pull request for README.md (preferable) or file an issue. If the source code is closed, you can say just "found N bugs in project X". Thank you.

go-fuzz's People

Contributors

aleksi avatar andybalholm avatar andybons avatar bayandin avatar bep avatar breml avatar btracey avatar cixtor avatar cryptix avatar dgryski avatar dvyukov avatar ericcornelissen avatar gregory-m avatar gy741 avatar hydroflame avatar joeshaw avatar josharian avatar marete avatar mdlayher avatar metalnem avatar nikai3d avatar obscuren avatar octo avatar pmezard avatar rlmcpherson avatar stephens2424 avatar tdewolff avatar thepudds avatar thomasdezeeuw avatar tklauser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-fuzz's Issues

internal/writerset: use of internal package not allowed

C:\Users\bbigras>go get -u github.com/dvyukov/go-fuzz/go-fuzz
package github.com/dvyukov/go-fuzz/go-fuzz
        imports github.com/dvyukov/go-fuzz/go-fuzz-defs
        imports github.com/dvyukov/go-fuzz/go-fuzz/internal/writerset
        imports github.com/dvyukov/go-fuzz/go-fuzz/internal/writerset
        imports github.com/dvyukov/go-fuzz/go-fuzz/internal/writerset: use of internal package not allowed

Windows 7 (64-bit)
go version go1.5beta1 windows/amd64

Support tests that accepts complex inputs

Currently go-fuzz mutates and supplies to a test a byte slice, however there are cases when a test needs more complex, structured input. For example, a regexp test could accept 3 strings (regexp, replacement string and input for replacement). Or a BLAS test could accept 2 matrices of floats. It is possible to manually convert the byte slice into any necessary structure (e.g. by json unmarshal), but is tedious for complex inputs, gives unnecessary coverage, in some cases can render some inputs inputs (e.g. if it does not json unmarshal successfully) and makes mutations suboptimal.

We could allow the test function to accept several arguments of arbitrary types:

func Fuzz(s1, s2 string, n int, m []float64, x MyStruct) int

and go-fuzz will supply all these arguments. If necessary go-fuzz-build can help by extracting types and generating some thunks.
Besides being very handy, it will also allow go-fuzz to do more efficient mutations (mutate each argument independently, or replace one of the arguments by the corresponding argument in another input).
I think that internally go-fuzz could use some very simple serialization format to represent such inputs (json, or maybe something simpler) to store them in files and communicate with the test process.

1.5 breaks fuzzing package main

golang/go#4210

With 1.4, you could still import a main package which meant testing commands was easy.

With 1.5, your parsing code has to be moved to its own package.

Probably worth mentioning in the README, even if there's no workaround.

Compilation fails on Windows; syscall functions undefined

Due to missing syscall functions this library does not compile on Windows. The following errors are produced:

λ go install github.com/dvyukov/go-fuzz/go-fuzz
# github.com/dvyukov/go-fuzz/go-fuzz
..\dvyukov\go-fuzz\go-fuzz\main.go:58: undefined: syscall.Setpriority
..\dvyukov\go-fuzz\go-fuzz\main.go:58: undefined: syscall.PRIO_PROCESS
..\dvyukov\go-fuzz\go-fuzz\slave.go:490: undefined: syscall.Mmap
..\dvyukov\go-fuzz\go-fuzz\slave.go:490: undefined: syscall.PROT_READ
..\dvyukov\go-fuzz\go-fuzz\slave.go:490: undefined: syscall.PROT_WRITE
..\dvyukov\go-fuzz\go-fuzz\slave.go:490: undefined: syscall.MAP_SHARED
λ go install github.com/dvyukov/go-fuzz/go-fuzz-dep
# github.com/dvyukov/go-fuzz/go-fuzz-dep
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:31: undefined: syscall.Mmap
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:31: undefined: syscall.PROT_READ
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:31: undefined: syscall.PROT_WRITE
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:31: undefined: syscall.MAP_SHARED
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:78: cannot use fd (type int) as type syscall.Handle in argument to syscall.Read
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:113: cannot use fd (type int) as type syscall.Handle in argument to syscall.Write
..\dvyukov\go-fuzz\go-fuzz-dep\main.go:130: cannot use fd (type int) as type syscall.Handle in argument to syscall.Write

go-fuzz-build builds fine though.

Additionally, cloning the git repository gives errors like:

λ go get github.com/dvyukov/go-fuzz
# cd .; git clone https://github.com/dvyukov/go-fuzz D:\Go\_projects\src\github.com\dvyukov\go-fuzz
Cloning into 'D:\Go\_projects\src\github.com\dvyukov\go-fuzz'...
error: unable to create file examples/gob/corpus/id:000000,orig:gob001660414 (Invalid argument)
error: unable to create file examples/gob/corpus/id:000001,orig:gob003084669 (Invalid argument)
error: unable to create file examples/gob/corpus/id:000002,orig:gob004976999 (Invalid argument)
error: unable to create file examples/gob/corpus/id:000003,orig:gob007769355 (Invalid argument)
error: unable to create file examples/gob/corpus/id:000004,orig:gob009259022 (Invalid argument)
error: unable to create file examples/gob/corpus/id:000005,orig:gob010917529 (Invalid argument)
[about a 1000 more]

go-fuzz-build fails

Execute go-fuzz-build as the readme suggests.

andrew@andrew-laptop:fuzz $ go version
go version devel +ada8cdb Fri Apr 24 21:52:30 2015 +0000 linux/amd64
andrew@andrew-laptop:fuzz $ go get github.com/dvyukov/go-fuzz/...
andrew@andrew-laptop:fuzz $ go-fuzz-build github.com/dvyukov/go-fuzz/examples/png
failed to scan dir 'pkg/tool': open pkg/tool: no such file or directory

go-fuzz-build is broken

When installing inside of a standard docker golang image, i am getting this:

root@c143409dc6e8:/go# go get github.com/dvyukov/go-fuzz/go-fuzz
root@c143409dc6e8:/go# go get github.com/dvyukov/go-fuzz/go-fuzz-build
# github.com/dvyukov/go-fuzz/go-fuzz-build
src/github.com/dvyukov/go-fuzz/go-fuzz-build/cover.go:292: undefined: strings.LastIndexByte

cover: 2746

the README examples have a coverage value which looks like a percentage (13%). In my runs I see something like

cover: 2746, uptime: 1m21s

which I can't make sense of given the information in the README. So likely one of the two needs to be updated.

panic inside Go runtime

I just had go-fuzz crash inside Go runtime, after Ctrl-C:

^C2015/04/30 00:35:15 shutting down...
runtime: newstack called from g=0xc208804fc0
    m=0xc20807e700 m->curg=0xc20812e7e0 m->g0=0xc2088050e0 m->gsignal=0xc208804fc0
runtime.onM(0xc208088e60)
    /usr/local/go/src/runtime/asm_amd64.s:235 +0x2f
runtime.morestackc()
    /usr/local/go/src/runtime/stack.c:885 +0x1e
runtime.sighandler(0x2, 0xc2080892d8, 0xc208089340, 0xc20812e7e0)
    /usr/local/go/src/runtime/signal_amd64x.c:44 +0x14
runtime.sigtramp(0x2dd, 0x0, 0x200000200000085, 0xc2086ffaa0, 0x5da6, 0xc20807e700, 0xc2080893f8, 0x1, 0x0, 0x0, ...)
    /usr/local/go/src/runtime/sys_darwin_amd64.s:229 +0x69
fatal error: runtime: wrong goroutine in newstack

runtime stack:
runtime.throw(0x5fb1d7)
    /usr/local/go/src/runtime/panic.go:491 +0xad
runtime.newstack()
    /usr/local/go/src/runtime/stack.c:710 +0x16b
runtime.morestack()
    /usr/local/go/src/runtime/asm_amd64.s:324 +0x7e

goroutine 15 [running]:

go version go1.4.2 darwin/amd64

Install issues on OSX

OSX 10.10.5

[vyrus]:[src]go version
go version go1.3.1 darwin/amd64
[vyrus]:[src]go get github.com/dvyukov/go-fuzz/go-fuzz
# github.com/dvyukov/go-fuzz/go-fuzz
github.com/dvyukov/go-fuzz/go-fuzz/master.go:89: syntax error: unexpected range, expecting {
github.com/dvyukov/go-fuzz/go-fuzz/master.go:93: non-declaration statement outside function body
github.com/dvyukov/go-fuzz/go-fuzz/master.go:101: non-declaration statement outside function body
github.com/dvyukov/go-fuzz/go-fuzz/master.go:102: non-declaration statement outside function body
github.com/dvyukov/go-fuzz/go-fuzz/master.go:104: non-declaration statement outside function body
github.com/dvyukov/go-fuzz/go-fuzz/master.go:105: syntax error: unexpected }

Put examples in another repo

The go-fuzz repository is abnormally large, and takes some time to fetch on poor connections. Perhaps you could move the non-essential assets to another repository?

panic: bad in cover.go

After running a few seconds. Seems quite random.

panic: bad

goroutine 18 [running]:
main.compareCover(0xc208ef0000, 0x10000, 0x10000, 0x7f050b169000, 0x10000, 0x210000, 0xc208f11160)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/cover.go:22 +0x141
main.(*Hub).updateMaxCover(0xc208040400, 0x7f050b169000, 0x10000, 0x210000, 0x0)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:288 +0xd1
main.(*Slave).noteNewInput(0xc20807a1c0, 0xc208f12440, 0xc, 0xe, 0x7f050b169000, 0x10000, 0x210000, 0x1, 0x1, 0x5)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:582 +0x74
main.(*Slave).testInputImpl(0xc20807a1c0, 0xc208042630, 0xc208f12440, 0xc, 0xe, 0x1, 0x5, 0x7f050b279000, 0x0, 0x100000)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:573 +0x368
main.(*Slave).testInput(0xc20807a1c0, 0xc208f12440, 0xc, 0xe, 0x1, 0x5)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:553 +0x66
main.(*Slave).smash(0xc20807a1c0, 0xc208280310, 0xe, 0xe, 0x0)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:548 +0x1854
main.(*Slave).triageInput(0xc20807a1c0, 0xc208280310, 0xe, 0xe, 0x0, 0x1, 0x1)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:286 +0x5bf
main.(*Slave).loop(0xc20807a1c0)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:151 +0x67c
created by main.slaveMain
        /src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:127 +0x9cd

goroutine 1 [select (no cases)]:
main.main()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:91 +0x1b3

goroutine 9 [IO wait]:
net.(*pollDesc).Wait(0xc208010290, 0x72, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:84 +0x47
net.(*pollDesc).WaitRead(0xc208010290, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:89 +0x43
net.(*netFD).accept(0xc208010230, 0x0, 0x7f050d525d30, 0xc208979178)
        /usr/local/go/src/net/fd_unix.go:419 +0x40b
net.(*TCPListener).AcceptTCP(0xc20802c018, 0xc20805add0, 0x0, 0x0)
        /usr/local/go/src/net/tcpsock_posix.go:234 +0x4e
net.(*TCPListener).Accept(0xc20802c018, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/net/tcpsock_posix.go:244 +0x4c
net/rpc.(*Server).Accept(0xc20800a100, 0x7f050d526518, 0xc20802c018)
        /usr/local/go/src/net/rpc/server.go:617 +0x3c
main.masterMain(0x7f050d526518, 0xc20802c018)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:68 +0x633
created by main.main
        /src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:81 +0x45c

goroutine 6 [syscall]:
os/signal.loop()
        /usr/local/go/src/os/signal/signal_unix.go:21 +0x1f
created by os/signal.init·1
        /usr/local/go/src/os/signal/signal_unix.go:27 +0x35

goroutine 8 [chan receive]:
main.func·001()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:52 +0x147
created by main.main
        /src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:61 +0xe6

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 37 [select]:
main.func·011()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:185 +0x5a6
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:206 +0xfc3

goroutine 11 [chan receive]:
main.masterLoop(0xc2080a4100)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:86 +0x87
created by main.masterMain
        /src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:64 +0x563

goroutine 13 [IO wait]:
net.(*pollDesc).Wait(0xc208010370, 0x72, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:84 +0x47
net.(*pollDesc).WaitRead(0xc208010370, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:89 +0x43
net.(*netFD).Read(0xc208010310, 0xc20899f000, 0x1000, 0x1000, 0x0, 0x7f050d525d30, 0xc2080eaba8)
        /usr/local/go/src/net/fd_unix.go:242 +0x40f
net.(*conn).Read(0xc20802c040, 0xc20899f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /usr/local/go/src/net/net.go:121 +0xdc
bufio.(*Reader).fill(0xc20804e5a0)
        /usr/local/go/src/bufio/bufio.go:97 +0x1ce
bufio.(*Reader).Read(0xc20804e5a0, 0xc208978f20, 0x1, 0x9, 0xc2080a4550, 0x0, 0x0)
        /usr/local/go/src/bufio/bufio.go:174 +0x26c
io.ReadAtLeast(0x7f050d527740, 0xc20804e5a0, 0xc208978f20, 0x1, 0x9, 0x1, 0x0, 0x0, 0x0)
        /usr/local/go/src/io/io.go:298 +0xf1
io.ReadFull(0x7f050d527740, 0xc20804e5a0, 0xc208978f20, 0x1, 0x9, 0x5ceb5d, 0x0, 0x0)
        /usr/local/go/src/io/io.go:316 +0x6d
encoding/gob.decodeUintReader(0x7f050d527740, 0xc20804e5a0, 0xc208978f20, 0x9, 0x9, 0x0, 0x1, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decode.go:121 +0x99
encoding/gob.(*Decoder).recvMessage(0xc2080a4500, 0x1)
        /usr/local/go/src/encoding/gob/decoder.go:76 +0x55
encoding/gob.(*Decoder).decodeTypeSequence(0xc2080a4500, 0xc20898a100, 0x16)
        /usr/local/go/src/encoding/gob/decoder.go:140 +0x47
encoding/gob.(*Decoder).DecodeValue(0xc2080a4500, 0x6e6ca0, 0xc20898a120, 0x16, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decoder.go:208 +0x192
encoding/gob.(*Decoder).Decode(0xc2080a4500, 0x6e6ca0, 0xc20898a120, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decoder.go:185 +0x297
net/rpc.(*gobClientCodec).ReadResponseHeader(0xc2089c09f0, 0xc20898a120, 0x0, 0x0)
        /usr/local/go/src/net/rpc/client.go:223 +0x5e
net/rpc.(*Client).input(0xc20804e660)
        /usr/local/go/src/net/rpc/client.go:109 +0xb6
created by net/rpc.NewClientWithCodec
        /usr/local/go/src/net/rpc/client.go:201 +0xd0

goroutine 14 [IO wait]:
net.(*pollDesc).Wait(0xc2080111e0, 0x72, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:84 +0x47
net.(*pollDesc).WaitRead(0xc2080111e0, 0x0, 0x0)
        /usr/local/go/src/net/fd_poll_runtime.go:89 +0x43
net.(*netFD).Read(0xc208011180, 0xc2089a3000, 0x1000, 0x1000, 0x0, 0x7f050d525d30, 0xc20897c598)
        /usr/local/go/src/net/fd_unix.go:242 +0x40f
net.(*conn).Read(0xc20802c1c8, 0xc2089a3000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /usr/local/go/src/net/net.go:121 +0xdc
bufio.(*Reader).fill(0xc20804ec00)
        /usr/local/go/src/bufio/bufio.go:97 +0x1ce
bufio.(*Reader).Read(0xc20804ec00, 0xc2089791b0, 0x1, 0x9, 0x5c5a0a, 0x0, 0x0)
        /usr/local/go/src/bufio/bufio.go:174 +0x26c
io.ReadAtLeast(0x7f050d527740, 0xc20804ec00, 0xc2089791b0, 0x1, 0x9, 0x1, 0x0, 0x0, 0x0)
        /usr/local/go/src/io/io.go:298 +0xf1
io.ReadFull(0x7f050d527740, 0xc20804ec00, 0xc2089791b0, 0x1, 0x9, 0x1, 0x0, 0x0)
        /usr/local/go/src/io/io.go:316 +0x6d
encoding/gob.decodeUintReader(0x7f050d527740, 0xc20804ec00, 0xc2089791b0, 0x9, 0x9, 0x0, 0x1, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decode.go:121 +0x99
encoding/gob.(*Decoder).recvMessage(0xc2080a4580, 0xc208134240)
        /usr/local/go/src/encoding/gob/decoder.go:76 +0x55
encoding/gob.(*Decoder).decodeTypeSequence(0xc2080a4580, 0xc20897b400, 0x16)
        /usr/local/go/src/encoding/gob/decoder.go:140 +0x47
encoding/gob.(*Decoder).DecodeValue(0xc2080a4580, 0x6e6c40, 0xc20897b480, 0x16, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decoder.go:208 +0x192
encoding/gob.(*Decoder).Decode(0xc2080a4580, 0x6e6c40, 0xc20897b480, 0x0, 0x0)
        /usr/local/go/src/encoding/gob/decoder.go:185 +0x297
net/rpc.(*gobServerCodec).ReadRequestHeader(0xc20898a270, 0xc20897b480, 0x0, 0x0)
        /usr/local/go/src/net/rpc/server.go:402 +0x5e
net/rpc.(*Server).readRequestHeader(0xc20800a100, 0x7f050d52bbc0, 0xc20898a270, 0x0, 0x0, 0xc20897b480, 0xc208979100, 0x0, 0x0)
        /usr/local/go/src/net/rpc/server.go:575 +0x97
net/rpc.(*Server).readRequest(0xc20800a100, 0x7f050d52bbc0, 0xc20898a270, 0xc2080a4400, 0xc20897aee0, 0x6e2ce0, 0x0, 0x0, 0x0, 0x0, ...)
        /usr/local/go/src/net/rpc/server.go:542 +0xa2
net/rpc.(*Server).ServeCodec(0xc20800a100, 0x7f050d52bbc0, 0xc20898a270)
        /usr/local/go/src/net/rpc/server.go:461 +0x6d
net/rpc.(*Server).ServeConn(0xc20800a100, 0x7f050d52baa8, 0xc20802c1c8)
        /usr/local/go/src/net/rpc/server.go:453 +0x208
created by net/rpc.(*Server).Accept
        /usr/local/go/src/net/rpc/server.go:621 +0x1f3

goroutine 16 [select]:
main.(*Hub).loop(0xc208040400)
        /src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:152 +0x22d1
created by main.newHub
        /src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:115 +0xe8b

goroutine 38 [select]:
main.func·012()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:212 +0x300
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:229 +0x1022

goroutine 39 [select]:
main.func·013()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:232 +0x143
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:237 +0x107d

goroutine 29 [syscall]:
syscall.Syscall(0x0, 0x10, 0xc209170000, 0x100000, 0x0, 0xc208976f60, 0xc20804fd40)
        /usr/local/go/src/syscall/asm_linux_amd64.s:21 +0x5
syscall.read(0x10, 0xc209170000, 0x100000, 0x100000, 0xc208976f60, 0x0, 0x0)
        /usr/local/go/src/syscall/zsyscall_linux_amd64.go:867 +0x6e
syscall.Read(0x10, 0xc209170000, 0x100000, 0x100000, 0x2, 0x0, 0x0)
        /usr/local/go/src/syscall/syscall_unix.go:136 +0x58
os.(*File).read(0xc20802c8f8, 0xc209170000, 0x100000, 0x100000, 0x2, 0x0, 0x0)
        /usr/local/go/src/os/file_unix.go:191 +0x5e
os.(*File).Read(0xc20802c8f8, 0xc209170000, 0x100000, 0x100000, 0x100000, 0x0, 0x0)
        /usr/local/go/src/os/file.go:95 +0x91
main.func·011()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:189 +0x198
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:206 +0xfc3

goroutine 30 [select]:
main.func·012()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:212 +0x300
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:229 +0x1022

goroutine 31 [select]:
main.func·013()
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:232 +0x143
created by main.newTestee
        /src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:237 +0x107d

encoding/json

Have you been fuzzing encoding/json yet? I noticed you worked on gob.

failed to parse package unicode/utf8

Go 1.5, Ubuntu x64. Tried experimentally adding a simple Fuzz method to sarama (https://github.com/Shopify/sarama). go build still works fine, but when I try and run go-fuzz-build I get the following error:

failed to parse package unicode/utf8: /tmp/go-fuzz-build000084784/src/unicode/utf8/utf8.go:385:6: expected operand, found 'range' (and 3 more errors)

Instructions for go get fail.

"go get github.com/dvyukov/go-fuzz/..." as readme suggests fails. One error is spdy was deleted. perhaps you can test from a fresh GOPATH

line numbers are wrong in crasher output

The fuzzed data caused a panic, and reported a stack trace. When I looked at the output, the line number made no sense. (It was the closing brace of a if err != nil { ... } block)

I only noticed when I ran go-fuzz-build with -workdir that the code is instrumented before building, which throws off line numbers. The //line directive would be helpful in mapping the code to the original line numbers.

Allow fuzzing multiple functions

In Prometheus' promql-package, there is four distinct parsers, all of which I'd like to fuzz.

Right now, I wrote all four of them into one Fuzz-function (see prometheus/prometheus#667 (comment)), but then I have to look through the traces to see which of these actually failed (and why).

Would it be possible to do something similar to the testing-package w. FuzzXXXX(in []byte) int? to allow fuzzing different parts of the system in one go?

workdir with ~ ends up in current folder

Example says:

$ go-fuzz -bin=./png-fuzz -corpus=examples/png/corpus -workdir=~/png-fuzz

Expect the workdir to be placed under HOME, but ends up in

<project-dir>/~/png-fuzz

uname -a && zsh --version
Linux bep-laptop 3.16.0-34-generic #47-Ubuntu SMP Fri Apr 10 18:02:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
zsh 5.0.5 (x86_64-pc-linux-gnu)

go-fuzz does not work with cgo

Hello, I previously used go-fuzz with Go 1.4.2, but now that I'm on 1.5.1, it no longer seems to work. In addition, when switching back to 1.4.2, it doesn't seem to work anymore either.

I just nuked my $GOPATH and reinstalled from scratch, just to see what would happen. It still doesn't seem to work. Any ideas?

Thanks for your time.

[zsh|matt@nerr-2]:~/git/go 0 % go version
go version go1.5.1 linux/amd64
[zsh|matt@nerr-2]:~/git/go 0 % go get github.com/mdlayher/ethernet                                                                                                                                       [zsh|matt@nerr-2]:~/git/go 2 % go get github.com/dvyukov/go-fuzz/go-fuzz                                                                            
[zsh|matt@nerr-2]:~/git/go 0 % go get github.com/dvyukov/go-fuzz/go-fuzz-build
[zsh|matt@nerr-2]:~/git/go 0 % cd src/github.com/mdlayher/ethernet 
[zsh|matt@nerr-2]:~/git/go/src/github.com/mdlayher/ethernet 0 (master) ± cat fuzz.go 
// +build gofuzz

package ethernet

func Fuzz(data []byte) int {
        f := new(Frame)
        if err := f.UnmarshalBinary(data); err != nil {
                return 0
        }

        if _, err := f.MarshalBinary(); err != nil {
                panic(err)
        }

        if err := f.UnmarshalFCS(data); err != nil {
                return 0
        }

        if _, err := f.MarshalFCS(); err != nil {
                panic(err)
        }

        return 1
}
[zsh|matt@nerr-2]:~/git/go/src/github.com/mdlayher/ethernet 0 (master) ± go-fuzz-build github.com/mdlayher/ethernet
[zsh|matt@nerr-2]:~/git/go/src/github.com/mdlayher/ethernet 0 *(master) ± go-fuzz -bin=./ethernet-fuzz.zip -workdir=fuzz/
2015/09/16 11:19:51 slaves: 8, corpus: 1 (3s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s
2015/09/16 11:19:54 slaves: 8, corpus: 1 (6s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 6s
2015/09/16 11:19:57 slaves: 8, corpus: 1 (9s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 9s
2015/09/16 11:20:00 slaves: 8, corpus: 1 (12s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 12s
2015/09/16 11:20:03 slaves: 8, corpus: 1 (15s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 15s
2015/09/16 11:20:06 slaves: 8, corpus: 1 (18s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 18s
2015/09/16 11:20:09 slaves: 8, corpus: 1 (21s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 21s
2015/09/16 11:20:12 slaves: 8, corpus: 1 (24s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 24s
2015/09/16 11:20:15 slaves: 8, corpus: 1 (27s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 27s
^C2015/09/16 11:20:17 shutting down...

Please provide LICENSE file / Clarify open source status?

Could you please provide a LICENSE file? At the moment I can find no details about copyright anywhere within go-fuzz or any kind of indication how open the code is. Without it a number of projects and companies will be unable to use your software.

Better minimization

Currently go-fuzz has 3 minimization strategies:

  • strip input suffix (O(N))
  • strip all possible subranges (O(N^2))
  • replace all individual bytes with '0' (O(N))

Here was suggested another strategy:
gogo/protobuf#91 (comment)
Namely:

  • extract all possible subranges (this is also O(N^2) so should be no worse than range removal)

Also what I hit several times when inputs are programs:

  • remove pairing brackets

strange crasher

Ran fuzzer for a short time, in crashers, got HASH.output with panic seemingly unrelated to my program.

fatal error: schedule: spinning with local work

runtime stack:
runtime.throw(0x594ad0, 0x22)
    /tmp/go-fuzz-build832835859/src/runtime/panic.go:543 +0x96
runtime.schedule()
    /tmp/go-fuzz-build832835859/src/runtime/proc1.go:1477 +0x247
runtime.mstart1()
    /tmp/go-fuzz-build832835859/src/runtime/proc1.go:743 +0x129
runtime.mstart()
    /tmp/go-fuzz-build832835859/src/runtime/proc1.go:703 +0x72

goroutine 1 [runnable]:
syscall.Syscall(0x0, 0x4, 0xc20803dea8, 0x8, 0x8, 0x8, 0x0)
    /tmp/go-fuzz-build832835859/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.read(0x4, 0xc20803dea8, 0x8, 0x8, 0x547760, 0x0, 0x0)
    /tmp/go-fuzz-build832835859/src/syscall/zsyscall_linux_amd64.go:792 +0x62
syscall.Read(0x4, 0xc20803dea8, 0x8, 0x8, 0x10, 0x0, 0x0)
    /tmp/go-fuzz-build832835859/src/syscall/syscall_unix.go:160 +0x54
github.com/dvyukov/go-fuzz/go-fuzz-dep.read(0x4, 0xc20803df20)
    /home/andrew/Desktop/gosrc/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:54 +0xc6
github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0x5aac48)
    /home/andrew/Desktop/gosrc/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:37 +0x3c
main.main()
    /tmp/go-fuzz-build832835859/src/go-fuzz-main/main.go:10 +0x2a

Is CGO supported at all?

i have a very simple case i'd like to test. something like the code below. the fuzz builder builds the zip file fine, however when I attempt to run it I get:

$ go-fuzz -bin ./p-fuzz.zip -workdir .
2015/09/17 06:54:57 bad input archive: missing file

here's the very simple code:

$ cat p.go 
package p

/*
#include <string.h>
*/
import "C"

func Fuzz(b []byte) int {
    s := C.CString(string(b))
    if C.strcmp((*C.char)(s), C.CString("test")) == 0 {
        panic("")
    }
    if len(b) > 4 {
        return 0
    }
    return 1
}

instrumentation fails for some x && y

Compilation of the following code fails after instrumentation:

type X bool

func foo(x, y X) X {
    return x && y
}
test.go:15: cannot use bool(x) && (func literal)() (type bool) as type X in return argument

Can't build with go-fuzz-build, import cycle not allowed

I ran go-fuzz-build github.com/dvyukov/go-fuzz/examples/png, and I got this error:

failed to execute go build: exit status 1
import cycle not allowed
package go-fuzz-main
        imports github.com/dvyukov/go-fuzz/examples/png
        imports bytes
        imports github.com/dvyukov/go-fuzz/go-fuzz-dep
        imports time
        imports internal/syscall/windows/registry
        imports github.com/dvyukov/go-fuzz/go-fuzz-dep

I get the same error trying to run it on my own code. I'm running Windows 7 64bit, go compiled from source at commit aadd84e0c4ac2476644d0f60b4873867c9549306, just after 1.5 beta 2.

Slave failing master not updating

Running with Go go version devel +aadd84e Sat Jul 18 01:35:25 2015 +0000 windows/amd64, after a couple of hours of running go-fuzz I get these error messages:

2015/07/19 21:09:09 slaves: 0, corpus: 570 (59m8s ago), crashers: 0, restarts: 1
/9999, execs: 355020636 (23109/sec), cover: 490, uptime: 4h16m
2015/07/19 21:09:09 sync call failed: unknown slave
2015/07/19 21:09:12 slaves: 0, corpus: 570 (59m11s ago), crashers: 0, restarts:
1/9999, execs: 355020636 (23104/sec), cover: 490, uptime: 4h16m
2015/07/19 21:09:12 sync call failed: unknown slave
2015/07/19 21:09:14 shutting down...
2015/07/19 21:09:15 sync call failed: unknown slave

It seems to me a slave has crashed and the master hasn't updated to remove the slave. The error comes from here:

log.Printf("sync call failed: %v", err)
.

reconsider priority assignment for valid inputs

Currently valid inputs (with result=1) receive 2x priority boost. This is good. However, if we have 2 valid inputs and 200 invalid ones (that examine various error paths), we actually want to mutate valid inputs 2x more frequently than all invalid ones. Valid inputs has much higher probability of uncovering new source code statements, while mutated invalid inputs will most likely bail out through the same error path.

Improve versifier

Currently versifer (automatic protocol reverse engineering) does only very basic analysis of text protocols. There are plenty of things that can be improved:

  • Rewrite analysis (currently is it more of a quick prototype), it probably should use some structured approach like Sequitur [0].
  • If a token sequence can be both, say, a list of key-value pairs and a key-value pair where the value is a list; versifer could build AST for both possibilities and then join them using ChoiceNode. Then, during generation we choose one of the possibilities.
  • Try to join several inputs into a single AST. For example, if one inputs contain key-value pair with alphanum value, while another inputs contain key-value pair with num value at the very same position; we could join both inputs and say that this a key-value pair that can contain both alphanum and num as value. This joining can be done on parts of the same input as well. For example, if we have an HTTP request with 10 headers, we can figure out that these headers have similar structure and build a common dictionary of header names and a common representation of header values.
  • Explore analysis of binary protocols (see [1] and [2]).
  • Better detection of text/binary protocols. I think I saw versifer being triggered for a binary protocol.
  • Better approach for mutations. Currently it does too many mutations. Also see whether there are other interesting mutations.
  • Better testing story. E.g. unit tests could test that it recognizes an input as, say, list of key-value pairs; while system tests could test that we can generate an output with required properties from given input in finite time.
  • Investigate how it works on some common inputs (xml, json, http, protobufs). This can uncover bugs in analysis and suggest new interesting mutation strategies.

[0] https://en.wikipedia.org/wiki/Sequitur_algorithm
[1] Discoverer: Automatic Protocol Reverse Engineering from Network Traces
http://research.microsoft.com/pubs/153196/discoverer-security07.pdf
[2] Reverse Engineering of Protocols from Network Traces
http://www.di.fc.ul.pt/~nuno/PAPERS/WCRE11.pdf

go-fuzz-build with '.'

andrew@andrew-laptop:fuzz $ go-fuzz-build .
failed to execute go build: exit status 1
can't load package: /tmp/go-fuzz-build703235414/src/go-fuzz-main/main.go:5:2: local import "." in non-local package
import cycle not allowed
package go-fuzz-main
    imports .
    imports .

I don't mind if you don't care to support this.

go-fuzz-build cannot rename temp files on Windows

C:\> go version
go version go1.4.2 windows/amd64

C:\> go-fuzz-build github.com/dvyukov/go-fuzz/examples/png
failed to rename file: rename C:\Users\chines\AppData\Local\Temp\go-fuzz471785897 C:\Users\chines\AppData\Local\Temp\go-fuzz-build807842546\src\unicode\utf8\utf
8.go: Cannot create a file when that file already exists.

It looks like the code is trying to use os.Rename to overwrite files after instrumenting them.

panic with new key-value logic

I received the following panic with go-fuzz a60c04b
while fuzzing github.com/Sereal/Sereal/Go/sereal.

Looks like the new key-value stuff that was just merged.

panic: runtime error: slice bounds out of range

goroutine 50 [running]:
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structureKeyValue(0xc82027bb00, 0x6, 0x8, 0x0, 0x0, 0x0)
        /home/dgryski/work/src/gocode/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:696 +0x75e
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structure(0xc82027bb00, 0x6, 0x8, 0x0, 0x0, 0x0)
        /home/dgryski/work/src/gocode/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:575 +0xdd
github.com/dvyukov/go-fuzz/go-fuzz/versifier.BuildVerse(0x0, 0xc8202e0330, 0xf, 0x2b, 0x10000)
        /home/dgryski/work/src/gocode/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:55 +0x1b9
main.(*Hub).loop(0xc820200e00)
        /home/dgryski/work/src/gocode/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:225 +0x19ed
created by main.newHub
        /home/dgryski/work/src/gocode/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:124 +0x10e7

go get fails due to bson

> mkdir /tmp/gp
> GOPATH=/tmp/gp
GOPATH=/tmp/gp
> go get github.com/dvyukov/go-fuzz/...
package github.com/dvyukov/go-fuzz/...
    imports github.com/dvyukov/go-fuzz/examples/bmp
    imports github.com/dvyukov/go-fuzz/examples/bson
    imports github.com/go-mgo/mgo/bson
    imports github.com/go-mgo/mgo/bson
    imports github.com/go-mgo/mgo/bson: cannot find package "github.com/go-mgo/mgo/bson" in any of:
    /home/user/go/src/github.com/go-mgo/mgo/bson (from $GOROOT)
    /tmp/gp/src/github.com/go-mgo/mgo/bson (from $GOPATH)

I don't think that go get … /... is the right approach, as it means installing a ton of dependencies just for the examples.

go-fuzz-dep: hang-up

Thanks for the nice stuff. Looks like go-fuzz-dep subprocesses on darwin/amd64 rarely hang up.

go version: git rev-parse HEAD
714291f2d80bab1599a866f266a4fc6546e61632

program hanged (timeout 10 seconds)

SIGABRT: abort
PC=0x51d6b m=0

goroutine 0 [idle]:
runtime.mach_semaphore_wait(0xd03, 0x0, 0x0, 0x2c3220, 0x2c3220, 0x23d060, 0x45de0, 0xffffffffffffffff, 0x0, 0x7fff5fbff76c, ...)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/sys_darwin_amd64.s:407 +0xb
runtime.semasleep1(0xffffffffffffffff, 0x0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/os1_darwin.go:380 +0xee
runtime.semasleep.func1()
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/os1_darwin.go:396 +0x30
runtime.systemstack(0x7fff5fbff770)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/asm_amd64.s:278 +0xb1
runtime.semasleep(0xffffffffffffffff, 0x0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/os1_darwin.go:397 +0x36
runtime.notesleep(0x23d468)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/lock_sema.go:169 +0x112
runtime.stopm()
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/proc1.go:1110 +0x127
runtime.findrunnable(0xc20801c000, 0x0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/proc1.go:1491 +0x6c2
runtime.schedule()
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/proc1.go:1600 +0x285
runtime.exitsyscall0(0xc208000140)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/proc1.go:2107 +0x183
runtime.mcall(0x7fff5fbff8f0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/asm_amd64.s:204 +0x5e

goroutine 1 [syscall]:
syscall.Syscall(0x4, 0x5, 0xc208051e80, 0x18, 0x12c9c0, 0x10, 0xc2080cf5b0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.write(0x5, 0xc208051e80, 0x18, 0x18, 0xc2080d2360, 0x0, 0x0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/syscall/zsyscall_darwin_amd64.go:1360 +0x62
syscall.Write(0x5, 0xc208051e80, 0x18, 0x18, 0xc2080d2360, 0x0, 0x0)
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/syscall/syscall_unix.go:176 +0x54
github.com/dvyukov/go-fuzz/go-fuzz-dep.FD.write(0x5, 0xc208051e80, 0x18, 0x18, 0x1fffe8, 0x0, 0x0)
        /swdev/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/sys_posix.go:27 +0x52
github.com/dvyukov/go-fuzz/go-fuzz-dep.write(0x5, 0xc208051f18, 0x3, 0x3)
        /swdev/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:83 +0x15b
github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0x1bffc0)
        /swdev/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:46 +0x212
main.main()
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/go-fuzz-main/main.go:10 +0x2a

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        /var/folders/7d/d3y9vsls2yd880k121jmzcyr0000gn/T/go-fuzz-build933145906/src/runtime/asm_amd64.s:1670 +0x1

rax    0xe
rbx    0xd03
rcx    0x7fff5fbff6f8
rdx    0x7fff5fbff770
rdi    0xd03
rsi    0x23d060
rbp    0x23d360
rsp    0x7fff5fbff6f8
r8     0x23d360
r9     0x0
r10    0x0
r11    0x286
r12    0x17c03e75
r13    0xeccf602d6
r14    0xeccf602d6
r15    0x23cda0
rip    0x51d6b
rflags 0x286
cs     0x7
fs     0x0
gs     0x0
exit status 2

False alarms?

I had lots of fun with go-fuzz this afternoon. I will create a PR for the README later.

But first a question.

I get some crashes that I cannot reproduce by running them one-by-one. I'm having a hard time figuring out what went wrong by reading the output -- but these are repeatedly reported by two similar inputs (in two different scenarios), so I guess there are two bugs I have to identify.

I would be grateful for any hints about how to interpret the output below.

First:

SIGABRT: abort
PC=0x41f4fb

goroutine 1 [running]:
runtime.atomicload(0xc20803419c, 0x0)
    /tmp/go-fuzz-build681797842/src/runtime/atomic_amd64x.c:14 +0xb fp=0xc20802b698 sp=0xc20802b690
runtime.chanrecv(0x5db9a0, 0xc208034180, 0xc20802b7a8, 0x4007fb20bbd3000, 0x400000)
    /tmp/go-fuzz-build681797842/src/runtime/chan.go:354 +0xe1 fp=0xc20802b738 sp=0xc20802b698
runtime.selectnbrecv(0x5db9a0, 0xc20802b7a8, 0xc208034180, 0xc208000100)
    /tmp/go-fuzz-build681797842/src/runtime/chan.go:566 +0x41 fp=0xc20802b768 sp=0xc20802b738
github.com/BurntSushi/toml.(*lexer).nextItem(0xc2080341e0, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build681797842/src/github.com/BurntSushi/toml/lex.go:84 +0xc0 fp=0xc20802b7d0 sp=0xc20802b768
github.com/BurntSushi/toml.(*parser).next(0xc208010620, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build681797842/src/github.com/BurntSushi/toml/parse.go:97 +0x79 fp=0xc20802b880 sp=0xc20802b7d0
github.com/BurntSushi/toml.(*parser).topLevel(0xc208010620, 0xe, 0xc208010610, 0x1, 0x3)
    /tmp/go-fuzz-build681797842/src/github.com/BurntSushi/toml/parse.go:139 +0xb8 fp=0xc20802baa0 sp=0xc20802b880
github.com/BurntSushi/toml.parse(0xc208010540, 0x63, 0xc208010620, 0x0, 0x0)
    /tmp/go-fuzz-build681797842/src/github.com/BurntSushi/toml/parse.go:81 +0x659 fp=0xc20802bba0 sp=0xc20802baa0
github.com/BurntSushi/toml.Decode(0xc208010540, 0x63, 0x5d5dc0, 0xc20803e050, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /tmp/go-fuzz-build681797842/src/github.com/BurntSushi/toml/decode.go:113 +0x9d fp=0xc20802bcc0 sp=0xc20802bba0
github.com/spf13/hugo/parser.HandleTOMLMetaData(0xc208010460, 0x63, 0x63, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build681797842/src/github.com/spf13/hugo/parser/frontmatter.go:254 +0x186 fp=0xc20802bd60 sp=0xc20802bcc0
github.com/spf13/hugo/parser.(*page).Metadata(0xc208036180, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build681797842/src/github.com/spf13/hugo/parser/page.go:77 +0x14f fp=0xc20802bdd0 sp=0xc20802bd60
github.com/bep/gobep-fuzz/hugo/parser.Fuzz(0x7fb20b95f000, 0x6e, 0x100000, 0x2)
    /tmp/go-fuzz-build681797842/src/github.com/bep/gobep-fuzz/hugo/parser/main.go:31 +0x2d0 fp=0xc20802be70 sp=0xc20802bdd0
github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0x6a0050, 0x734220, 0x83c, 0x83c)
    /home/bep/dev/go/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:64 +0x309 fp=0xc20802bf70 sp=0xc20802be70
main.main()
    /tmp/go-fuzz-build681797842/src/go-fuzz-main/main.go:10 +0x4e fp=0xc20802bf98 sp=0xc20802bf70
runtime.main()
    /tmp/go-fuzz-build681797842/src/runtime/proc.go:63 +0xf3 fp=0xc20802bfe0 sp=0xc20802bf98
runtime.goexit()
    /tmp/go-fuzz-build681797842/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc20802bfe8 sp=0xc20802bfe0

rax     0x0
rbx     0x0
rcx     0xc208034180
rdx     0xc208034180
rdi     0xc20802b7c8
rsi     0x61
rbp     0x0
rsp     0xc20802b690
r8      0x64
r9      0x30
r10     0x30
r11     0x62abc0
r12     0x0
r13     0x0
r14     0x3
r15     0x10
rip     0x41f4fb
rflags  0x206
cs      0x33
fs      0x0
gs      0x0
exit status 2

Second:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x50 pc=0x4696bd]

goroutine 1 [running]:
github.com/spf13/hugo/hugolib.getShortcodeTemplate(0x0, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcode.go:672 +0xad
github.com/spf13/hugo/hugolib.renderShortcode(0x0, 0x0, 0x0, 0x0, 0x0, 0xae9de0, 0xc2080fa8c0, 0x0, 0x0, 0x0, ...)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcode.go:245 +0x13c
github.com/spf13/hugo/hugolib.extractAndRenderShortcodes(0xc2080fc618, 0x3, 0xc208038c00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcode.go:341 +0x57d
github.com/spf13/hugo/hugolib.HandleShortcodes(0xc2080fc618, 0x3, 0xc208038c00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcode.go:174 +0xcd
github.com/bep/gobep-fuzz/hugo/shortcode.Fuzz(0x7f7ded4cd000, 0x3, 0x100000, 0x0)
    /tmp/go-fuzz-build909848046/src/github.com/bep/gobep-fuzz/hugo/shortcode/main.go:29 +0x1bf
github.com/dvyukov/go-fuzz/go-fuzz-dep.Main(0xe19a08, 0x1018740, 0x3ab0, 0x3ab0)
    /home/bep/dev/go/src/github.com/dvyukov/go-fuzz/go-fuzz-dep/main.go:64 +0x309
main.main()
    /tmp/go-fuzz-build909848046/src/go-fuzz-main/main.go:10 +0x4e

goroutine 23 [runnable]:
github.com/spf13/hugo/hugolib.(*pagelexer).errorf(0xc208052090, 0xd8c650, 0x19, 0x0, 0x0, 0x0, 0xc208055500)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcodeparser.go:314 +0xf6
github.com/spf13/hugo/hugolib.lexInsideShortcode(0xc208052090, 0xe19c08)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcodeparser.go:705 +0x300
github.com/spf13/hugo/hugolib.(*pagelexer).runShortcodeLexer(0xc208052090)
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcodeparser.go:220 +0xc7
created by github.com/spf13/hugo/hugolib.newShortcodeLexer
    /tmp/go-fuzz-build909848046/src/github.com/spf13/hugo/hugolib/shortcodeparser.go:210 +0x19f
exit status 2

go-fuzz-build fails on github.com/golang/freetype/raster/stroke.go

Hello,

Running go-fuzz-build on github.com/golang/freetype/truetype fails with:

workdir: /tmp/go-fuzz-build120675630
workdir: /tmp/go-fuzz-build334498485
failed to execute go build: exit status 2
# github.com/golang/freetype/raster
/tmp/go-fuzz-build334498485/src/github.com/golang/freetype/raster/stroke.go:279[...]: undefined: golang in golang.org

It happens because the annotated source looks like:

_go_fuzz_dep_.Sonar(v1, golang.org/x/image/math/fixed.Int52_12(fixed.Int52_12(1<<12)), 662402)

instead of

_go_fuzz_dep_.Sonar(v1, fixed.Int52_12(fixed.Int52_12(1<<12)), 662402)

It comes from https://github.com/dvyukov/go-fuzz/blob/master/go-fuzz-build/cover.go#L288 returning the "fully qualified" type.

Removing everything from typstr before and including the last slash fixes the issue. I can make a pull-request if you want but I have not dug enough to know who to blame. Maybe that is a bug in golang.org/x/tools/go/types.

fuzzing github.com/andybalholm/cascadia crashes versifier

When I try to fuzz the CSS selector parsing code in github.com/andybalholm/cascadia, I get the following panic:

panic: runtime error: slice bounds out of range

goroutine 28 [running]:
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structureKeyValue(0xc820328180, 0x2, 0x2, 0x0, 0x0, 0x0)
/Users/andy/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:696 +0x489
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structure(0xc820328180, 0x2, 0x2, 0x0, 0x0, 0x0)
/Users/andy/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:575 +0xdd
github.com/dvyukov/go-fuzz/go-fuzz/versifier.BuildVerse(0xc82027a1b0, 0xc82020a960, 0x6, 0x6, 0x10000)
/Users/andy/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:55 +0x1b9
main.(*Hub).loop(0xc820224100)
/Users/andy/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:236 +0x1c2c
created by main.newHub
/Users/andy/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:115 +0xe83

write better documentation

Topics that need to be covered:

  • how to write good Fuzz functions (checking for logical bugs, cross checking different implementations, examining as much code as possible, testing functions that require more complex inputs and not just []byte)
  • how to use several Fuzz functions in a single package
  • corpus collection

crashers format unclear

according to the readme, the file without suffix should have the input. However, I repeatedly see the suffixless (and quoted) file contain "SELECT", whereas the corresponding .output file contains something along the lines of "SELECT*FROM F group by-0-1,0-1,0-1,0-1,x-1,0-1" created from

func Fuzz(data []byte) int {
    sql := string(data)
    fmt.Println(sql)

Shouldn't the above code's output match the suffixless file (mod quoting)?

Example instance here:
tbg/cockroach@4f25931

GO15VENDOREXPERIMENT is not supported

hi,
I met a problem when I used go-fuzz-build on my gocmpp project, details like below:

$go-fuzz-build github.com/bigwhite/gocmpp
can't find imported package golang.org/x/text/transform

I have checked the env for several times and make sure that golang.org/x/text/transform is at its right place.

Any ideas? Thanks for your time.

cover.go:41: missing function body

I have this problem on Linux but not on Windows.

go get github.com/dvyukov/go-fuzz/go-fuzz
# github.com/dvyukov/go-fuzz/go-fuzz
GOPATH/src/github.com/dvyukov/go-fuzz/go-fuzz/cover.go:41: missing function body

go version go1.4.2 linux/386

Generate runnable example for crashers?

This would make reproducing the bug for debugging, and submitting upstream, pretty easy. A few alternatives come to mind:

A. Create a new fuzz_<hash>_test.go, embedding contents of fuzz.go except func Fuzz renamed for uniqueness:

package pkgname

func Fuzz<hash>(data []byte) int {
...
}

func TestFuzz<hash>(t *testing) {
    Fuzz<hash>([]byte("contents of crashers/x.quote here"))
}

(if user defined helper functions in fuzz.go, this can still result in name conflicts)

B. Assuming upstream has the fuzz framework in place, just write a new command. Running it will require e.g. go run -tags gofuzz workdir/crashers/<hash>.main.go.

package main

import "github.com/jdoe/system-under-test/pkgname"

func main() {
    pkgname.Fuzz([]byte("contents of crashers/x.quote here"))
}

C. If upstream doesn't have func Fuzz in place, it might make more sense to generate a whole standalone copy of fuzz.go with a func main() embedded in it. Adjusting imports makes this more difficult, as the typical idiom seems to be to put func Fuzz in the same package as the system under test (and that's needed for fuzzing internal functions).

panic running fuzzer

(I'm using go version devel +fbb4c74 Sat May 2 02:48:32 2015 +0000 darwin/amd64, as I couldn't get the fuzzer to run with go1.4.2.)

After running the fuzzer for a few seconds, I get this:

2015/05/02 04:13:15 slaves: 8, corpus: 1 (3s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0.00%, uptime: 3s
2015/05/02 04:13:18 slaves: 8, corpus: 1 (6s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0.25%, uptime: 6s
2015/05/02 04:13:21 slaves: 8, corpus: 1 (9s ago), crashers: 1, restarts: 1/1, execs: 1793 (199/sec), cover: 0.25%, uptime: 9s
2015/05/02 04:13:24 slaves: 8, corpus: 1 (12s ago), crashers: 1, restarts: 1/1, execs: 3526 (294/sec), cover: 0.25%, uptime: 12s
2015/05/02 04:13:27 slaves: 8, corpus: 1 (15s ago), crashers: 1, restarts: 1/1, execs: 5314 (354/sec), cover: 0.25%, uptime: 15s
2015/05/02 04:13:30 slaves: 8, corpus: 1 (18s ago), crashers: 1, restarts: 1/1, execs: 7095 (394/sec), cover: 0.25%, uptime: 18s
2015/05/02 04:13:33 slaves: 8, corpus: 1 (21s ago), crashers: 1, restarts: 1/1, execs: 8859 (422/sec), cover: 0.25%, uptime: 21s
2015/05/02 04:13:36 slaves: 8, corpus: 1 (24s ago), crashers: 1, restarts: 1/1, execs: 10638 (443/sec), cover: 0.25%, uptime: 24s
2015/05/02 04:13:39 slaves: 8, corpus: 1 (27s ago), crashers: 1, restarts: 1/1, execs: 12448 (461/sec), cover: 0.25%, uptime: 27s
2015/05/02 04:13:42 slaves: 8, corpus: 1 (30s ago), crashers: 1, restarts: 1/1, execs: 14277 (476/sec), cover: 0.25%, uptime: 30s
2015/05/02 04:13:45 slaves: 8, corpus: 1 (33s ago), crashers: 1, restarts: 1/1, execs: 16125 (489/sec), cover: 0.25%, uptime: 33s
2015/05/02 04:13:48 slaves: 8, corpus: 1 (36s ago), crashers: 1, restarts: 1/1, execs: 17982 (499/sec), cover: 0.25%, uptime: 36s
2015/05/02 04:13:51 slaves: 8, corpus: 1 (39s ago), crashers: 1, restarts: 1/1, execs: 19850 (509/sec), cover: 0.25%, uptime: 39s
fatal error: acquireSudog: found s.elem != nil in cache

goroutine 60540 [running]:
runtime.throw(0x506810, 0x2a)
    /Users/antoine/go/src/runtime/panic.go:543 +0x96 fp=0xc208119ba8 sp=0xc208119b90
runtime.acquireSudog(0xc208181540)
    /Users/antoine/go/src/runtime/proc.go:232 +0x485 fp=0xc208119c48 sp=0xc208119ba8
runtime.selectgoImpl(0xc208119f40, 0x0, 0x18)
    /Users/antoine/go/src/runtime/select.go:369 +0x883 fp=0xc208119df0 sp=0xc208119c48
runtime.selectgo(0xc208119f40)
    /Users/antoine/go/src/runtime/select.go:212 +0x12 fp=0xc208119e10 sp=0xc208119df0
main.newTestee.func1(0xc208122080)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:94 +0x5bf fp=0xc208119fd8 sp=0xc208119e10
runtime.goexit()
    /Users/antoine/go/src/runtime/asm_amd64.s:1670 +0x1 fp=0xc208119fe0 sp=0xc208119fd8
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:115 +0xca3

goroutine 1 [select (no cases)]:
main.main()
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:87 +0x1bd

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /Users/antoine/go/src/runtime/asm_amd64.s:1670 +0x1

goroutine 7 [syscall]:
os/signal.loop()
    /Users/antoine/go/src/os/signal/signal_unix.go:22 +0x1f
created by os/signal.init.1
    /Users/antoine/go/src/os/signal/signal_unix.go:28 +0x3f

goroutine 8 [chan receive]:
main.main.func1()
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:48 +0x138
created by main.main
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:54 +0xe0

goroutine 9 [IO wait]:
net.runtime_pollWait(0xa66350, 0x72, 0xc208016210)
    /Users/antoine/go/src/runtime/netpoll.go:157 +0x63
net.(*pollDesc).Wait(0xc20800a370, 0x72, 0x0, 0x0)
    /Users/antoine/go/src/net/fd_poll_runtime.go:73 +0x41
net.(*pollDesc).WaitRead(0xc20800a370, 0x0, 0x0)
    /Users/antoine/go/src/net/fd_poll_runtime.go:78 +0x3d
net.(*netFD).accept(0xc20800a310, 0x0, 0xa60050, 0xc208016210)
    /Users/antoine/go/src/net/fd_unix.go:385 +0x21d
net.(*TCPListener).AcceptTCP(0xc208030000, 0xc20809be28, 0x0, 0x0)
    /Users/antoine/go/src/net/tcpsock_posix.go:254 +0x50
net.(*TCPListener).Accept(0xc208030000, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/net/tcpsock_posix.go:264 +0x40
net/rpc.(*Server).Accept(0xc208021cc0, 0xa653a8, 0xc208030000)
    /Users/antoine/go/src/net/rpc/server.go:618 +0x3c
main.masterMain(0xa653a8, 0xc208030000)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:59 +0x5f9
created by main.main
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/main.go:77 +0x48c

goroutine 11 [runnable]:
syscall.Syscall(0x3, 0x7, 0xc20809f000, 0x1000, 0x1f, 0x0, 0x0)
    /Users/antoine/go/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.read(0x7, 0xc20809f000, 0x1000, 0x1000, 0x72, 0x0, 0x0)
    /Users/antoine/go/src/syscall/zsyscall_darwin_amd64.go:970 +0x62
syscall.Read(0x7, 0xc20809f000, 0x1000, 0x1000, 0xffffffffffffff01, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall_unix.go:160 +0x54
net.(*netFD).Read(0xc20800a380, 0xc20809f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/net/fd_unix.go:228 +0x17e
net.(*conn).Read(0xc208030020, 0xc20809f000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/net/net.go:124 +0xe7
bufio.(*Reader).fill(0xc2080f6060)
    /Users/antoine/go/src/bufio/bufio.go:97 +0x1d6
bufio.(*Reader).Read(0xc2080f6060, 0xc2080f4120, 0x1, 0x9, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/bufio/bufio.go:207 +0x263
io.ReadAtLeast(0xa66520, 0xc2080f6060, 0xc2080f4120, 0x1, 0x9, 0x1, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:298 +0xf4
io.ReadFull(0xa66520, 0xc2080f6060, 0xc2080f4120, 0x1, 0x9, 0xc2080d2370, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:316 +0x69
encoding/gob.decodeUintReader(0xa66520, 0xc2080f6060, 0xc2080f4120, 0x9, 0x9, 0x0, 0x1, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decode.go:121 +0x95
encoding/gob.(*Decoder).recvMessage(0xc2080d2300, 0xc208134bf0)
    /Users/antoine/go/src/encoding/gob/decoder.go:76 +0x61
encoding/gob.(*Decoder).decodeTypeSequence(0xc2080d2300, 0x54c800, 0xc2080d2300)
    /Users/antoine/go/src/encoding/gob/decoder.go:140 +0x4a
encoding/gob.(*Decoder).DecodeValue(0xc2080d2300, 0x325b20, 0xc2080aa000, 0x16, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decoder.go:208 +0x1a0
encoding/gob.(*Decoder).Decode(0xc2080d2300, 0x325b20, 0xc2080aa000, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decoder.go:185 +0x28c
net/rpc.(*gobClientCodec).ReadResponseHeader(0xc2080dc5a0, 0xc2080aa000, 0x0, 0x0)
    /Users/antoine/go/src/net/rpc/client.go:223 +0x58
net/rpc.(*Client).input(0xc2080f6120)
    /Users/antoine/go/src/net/rpc/client.go:109 +0xc6
created by net/rpc.NewClientWithCodec
    /Users/antoine/go/src/net/rpc/client.go:201 +0xd6

goroutine 18 [chan receive]:
main.masterLoop(0xc2080fe000)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:63 +0x86
created by main.masterMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/master.go:55 +0x52e

goroutine 19 [IO wait]:
net.runtime_pollWait(0xa661d0, 0x72, 0xc208121000)
    /Users/antoine/go/src/runtime/netpoll.go:157 +0x63
net.(*pollDesc).Wait(0xc2080a05a0, 0x72, 0x0, 0x0)
    /Users/antoine/go/src/net/fd_poll_runtime.go:73 +0x41
net.(*pollDesc).WaitRead(0xc2080a05a0, 0x0, 0x0)
    /Users/antoine/go/src/net/fd_poll_runtime.go:78 +0x3d
net.(*netFD).Read(0xc2080a0540, 0xc208121000, 0x1000, 0x1000, 0x0, 0xa60050, 0xc208016210)
    /Users/antoine/go/src/net/fd_unix.go:232 +0x22d
net.(*conn).Read(0xc20809c050, 0xc208121000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/net/net.go:124 +0xe7
bufio.(*Reader).fill(0xc208124000)
    /Users/antoine/go/src/bufio/bufio.go:97 +0x1d6
bufio.(*Reader).Read(0xc208124000, 0xc208126000, 0x1, 0x9, 0x756ea150a27f68, 0x0, 0x0)
    /Users/antoine/go/src/bufio/bufio.go:207 +0x263
io.ReadAtLeast(0xa66520, 0xc208124000, 0xc208126000, 0x1, 0x9, 0x1, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:298 +0xf4
io.ReadFull(0xa66520, 0xc208124000, 0xc208126000, 0x1, 0x9, 0xc208110ec0, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:316 +0x69
encoding/gob.decodeUintReader(0xa66520, 0xc208124000, 0xc208126000, 0x9, 0x9, 0x0, 0x1, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decode.go:121 +0x95
encoding/gob.(*Decoder).recvMessage(0xc208122000, 0xc20803c970)
    /Users/antoine/go/src/encoding/gob/decoder.go:76 +0x61
encoding/gob.(*Decoder).decodeTypeSequence(0xc208122000, 0x54c800, 0xc208122000)
    /Users/antoine/go/src/encoding/gob/decoder.go:140 +0x4a
encoding/gob.(*Decoder).DecodeValue(0xc208122000, 0x325ac0, 0xc2081b6500, 0x16, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decoder.go:208 +0x1a0
encoding/gob.(*Decoder).Decode(0xc208122000, 0x325ac0, 0xc2081b6500, 0x0, 0x0)
    /Users/antoine/go/src/encoding/gob/decoder.go:185 +0x28c
net/rpc.(*gobServerCodec).ReadRequestHeader(0xc2080aa0f0, 0xc2081b6500, 0x0, 0x0)
    /Users/antoine/go/src/net/rpc/server.go:403 +0x58
net/rpc.(*Server).readRequestHeader(0xc208021cc0, 0xaa0100, 0xc2080aa0f0, 0x0, 0x0, 0xc2081b6500, 0xc20803cc00, 0x0, 0x0)
    /Users/antoine/go/src/net/rpc/server.go:576 +0x93
net/rpc.(*Server).readRequest(0xc208021cc0, 0xaa0100, 0xc2080aa0f0, 0xc208021cc0, 0xc208126020, 0xc2080fe100, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/go/src/net/rpc/server.go:543 +0x8e
net/rpc.(*Server).ServeCodec(0xc208021cc0, 0xaa0100, 0xc2080aa0f0)
    /Users/antoine/go/src/net/rpc/server.go:462 +0x6d
net/rpc.(*Server).ServeConn(0xc208021cc0, 0xa66470, 0xc20809c050)
    /Users/antoine/go/src/net/rpc/server.go:454 +0x4ef
created by net/rpc.(*Server).Accept
    /Users/antoine/go/src/net/rpc/server.go:622 +0x226

goroutine 20 [chan receive]:
net/rpc.(*Client).Call(0xc2080f6120, 0x4b7750, 0x11, 0x40f040, 0xc20883a000, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/net/rpc/client.go:315 +0xd0
main.(*Hub).loop(0xc2081ca000)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:201 +0x17e1
created by main.newHub
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:88 +0x727

goroutine 21 [runnable]:
syscall.Syscall(0x3, 0xf, 0xc2080165f0, 0x10, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.read(0xf, 0xc2080165f0, 0x10, 0x10, 0xc208016600, 0x0, 0x0)
    /Users/antoine/go/src/syscall/zsyscall_darwin_amd64.go:970 +0x62
syscall.Read(0xf, 0xc2080165f0, 0x10, 0x10, 0xc2080165f0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall_unix.go:160 +0x54
os.(*File).read(0xc20812e158, 0xc2080165f0, 0x10, 0x10, 0x46f9c0, 0x0, 0x0)
    /Users/antoine/go/src/os/file_unix.go:211 +0x82
os.(*File).Read(0xc20812e158, 0xc2080165f0, 0x10, 0x10, 0x3423a0, 0x0, 0x0)
    /Users/antoine/go/src/os/file.go:95 +0x8d
io.ReadAtLeast(0xd00088, 0xc20812e158, 0xc2080165f0, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:298 +0xf4
io.ReadFull(0xd00088, 0xc20812e158, 0xc2080165f0, 0x10, 0x10, 0x10, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:316 +0x69
encoding/binary.Read(0xd00088, 0xc20812e158, 0xd000d8, 0x6c83a8, 0x321f80, 0xc208017650, 0x0, 0x0)
    /Users/antoine/go/src/encoding/binary/binary.go:216 +0x12b3
main.(*Testee).test(0xc208216b00, 0xc2081ae7d0, 0x5, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:184 +0x5ad
main.(*Slave).exec(0xc20818e180, 0xc2081ae7d0, 0x5, 0x8, 0x113, 0x200, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:431 +0x160
main.(*Slave).testInput(0xc20818e180, 0xc2081ae7d0, 0x5, 0x8, 0x1)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:406 +0x147
main.(*Slave).loop(0xc20818e180)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:107 +0xe15
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 22 [runnable]:
syscall.ByteSliceFromString(0xc208018000, 0xccf, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:51 +0x129
syscall.BytePtrFromString(0xc208018000, 0xccf, 0xc208826220, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:65 +0x3e
syscall.SlicePtrFromStrings(0xc2084ba380, 0x31, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:85 +0xd9
syscall.forkExec(0x7fff5fbfe66e, 0xd, 0xc2088260d0, 0x1, 0x1, 0xc208187840, 0xc2084822d0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:156 +0x1d3
syscall.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2088260d0, 0x1, 0x1, 0xc208187840, 0x4, 0x8, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:238 +0x6e
os.startProcess(0x7fff5fbfe66e, 0xd, 0xc2088260d0, 0x1, 0x1, 0xc208187a90, 0xc2084ba380, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_posix.go:45 +0x40c
os.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2088260d0, 0x1, 0x1, 0xc208187a90, 0x4, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:24 +0x6c
os/exec.(*Cmd).Start(0xc2084b23c0, 0x0, 0x0)
    /Users/antoine/go/src/os/exec/exec.go:319 +0x894
main.newTestee(0x7fff5fbfe66e, 0xd, 0xc2080929b0, 0x46, 0x2910000, 0x10000, 0x110000, 0x2920000, 0x100000, 0x100000, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:55 +0x919
main.(*Slave).exec(0xc20818e240, 0xc2088260b0, 0x2, 0x8, 0x520, 0x555, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:428 +0x10a
main.(*Slave).testInput(0xc20818e240, 0xc2088260b0, 0x2, 0x8, 0x1)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:406 +0x147
main.(*Slave).loop(0xc20818e240)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:107 +0xe15
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 23 [runnable]:
syscall.ByteSliceFromString(0xc2080200c0, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:51 +0x129
syscall.BytePtrFromString(0xc2080200c0, 0x37, 0xc2081fb830, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:65 +0x3e
syscall.SlicePtrFromStrings(0xc208212a80, 0x31, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:85 +0xd9
syscall.forkExec(0x7fff5fbfe66e, 0xd, 0xc208016600, 0x1, 0x1, 0xc20813f6f0, 0xc2081facf0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:156 +0x1d3
syscall.StartProcess(0x7fff5fbfe66e, 0xd, 0xc208016600, 0x1, 0x1, 0xc20813f6f0, 0x4, 0x8, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:238 +0x6e
os.startProcess(0x7fff5fbfe66e, 0xd, 0xc208016600, 0x1, 0x1, 0xc20813f940, 0xc208212a80, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_posix.go:45 +0x40c
os.StartProcess(0x7fff5fbfe66e, 0xd, 0xc208016600, 0x1, 0x1, 0xc20813f940, 0x4, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:24 +0x6c
os/exec.(*Cmd).Start(0xc2084cb2c0, 0x0, 0x0)
    /Users/antoine/go/src/os/exec/exec.go:319 +0x894
main.newTestee(0x7fff5fbfe66e, 0xd, 0xc208092b90, 0x46, 0x2a20000, 0x10000, 0x110000, 0x2a30000, 0x100000, 0x100000, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:55 +0x919
main.(*Slave).exec(0xc20818e300, 0xc208017610, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:428 +0x10a
main.(*Slave).minimizeInput(0xc20818e300, 0xc2081ae6f0, 0x4, 0x8, 0xc20822e201, 0xc20813fd30, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:218 +0x4ba
main.(*Slave).processCrasher(0xc20818e300, 0xc2081ae6f0, 0x4, 0x8, 0xc208060d00, 0x348, 0x680, 0xc2081d2180, 0x79, 0x80, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:186 +0x93
main.(*Slave).loop(0xc20818e300)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:75 +0x35f
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 24 [semacquire]:
sync.runtime_Semacquire(0x6c8ac8)
    /Users/antoine/go/src/runtime/sema.go:43 +0x2d
sync.(*RWMutex).Lock(0x6c8ac0)
    /Users/antoine/go/src/sync/rwmutex.go:87 +0xa4
syscall.forkExec(0x7fff5fbfe66e, 0xd, 0xc2081ae460, 0x1, 0x1, 0xc208143840, 0xc2080aaf90, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:183 +0x32e
syscall.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2081ae460, 0x1, 0x1, 0xc208143840, 0x4, 0x8, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:238 +0x6e
os.startProcess(0x7fff5fbfe66e, 0xd, 0xc2081ae460, 0x1, 0x1, 0xc208143a90, 0xc20848e380, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_posix.go:45 +0x40c
os.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2081ae460, 0x1, 0x1, 0xc208143a90, 0x4, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:24 +0x6c
os/exec.(*Cmd).Start(0xc208221a40, 0x0, 0x0)
    /Users/antoine/go/src/os/exec/exec.go:319 +0x894
main.newTestee(0x7fff5fbfe66e, 0xd, 0xc208092d70, 0x46, 0x2b30000, 0x10000, 0x110000, 0x2b40000, 0x100000, 0x100000, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:55 +0x919
main.(*Slave).exec(0xc20818e3c0, 0xc2081ae3f0, 0x2, 0x8, 0x520, 0x555, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:428 +0x10a
main.(*Slave).testInput(0xc20818e3c0, 0xc2081ae3f0, 0x2, 0x8, 0x1)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:406 +0x147
main.(*Slave).loop(0xc20818e3c0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:107 +0xe15
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 25 [runnable]:
sync.runtime_Semacquire(0x6c8acc)
    /Users/antoine/go/src/runtime/sema.go:43 +0x2d
sync.(*RWMutex).RLock(0x6c8ac0)
    /Users/antoine/go/src/sync/rwmutex.go:36 +0x5f
os.Pipe(0xc208030030, 0xc208030038, 0x0, 0x0)
    /Users/antoine/go/src/os/pipe_bsd.go:17 +0x52
main.newTestee(0x7fff5fbfe66e, 0xd, 0xc208092f50, 0x46, 0x2c40000, 0x10000, 0x110000, 0x2c50000, 0x100000, 0x100000, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:37 +0x134
main.(*Slave).exec(0xc20818e480, 0xc208016350, 0x2, 0x8, 0x113, 0x200, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:428 +0x10a
main.(*Slave).testInput(0xc20818e480, 0xc208016350, 0x2, 0x8, 0x1)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:406 +0x147
main.(*Slave).loop(0xc20818e480)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:107 +0xe15
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 26 [runnable]:
syscall.Syscall(0x3, 0x22, 0xc208198610, 0x10, 0x10, 0x0, 0x0)
    /Users/antoine/go/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.read(0x22, 0xc208198610, 0x10, 0x10, 0xc208198600, 0x0, 0x0)
    /Users/antoine/go/src/syscall/zsyscall_darwin_amd64.go:970 +0x62
syscall.Read(0x22, 0xc208198610, 0x10, 0x10, 0xc208198610, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall_unix.go:160 +0x54
os.(*File).read(0xc2084be010, 0xc208198610, 0x10, 0x10, 0x46f9c0, 0x0, 0x0)
    /Users/antoine/go/src/os/file_unix.go:211 +0x82
os.(*File).Read(0xc2084be010, 0xc208198610, 0x10, 0x10, 0x3423a0, 0x0, 0x0)
    /Users/antoine/go/src/os/file.go:95 +0x8d
io.ReadAtLeast(0xd00088, 0xc2084be010, 0xc208198610, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:298 +0xf4
io.ReadFull(0xd00088, 0xc2084be010, 0xc208198610, 0x10, 0x10, 0x10, 0x0, 0x0)
    /Users/antoine/go/src/io/io.go:316 +0x69
encoding/binary.Read(0xd00088, 0xc2084be010, 0xd000d8, 0x6c83a8, 0x321f80, 0xc2081985b0, 0x0, 0x0)
    /Users/antoine/go/src/encoding/binary/binary.go:216 +0x12b3
main.(*Testee).test(0xc2087fa700, 0xc2081980c0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:184 +0x5ad
main.(*Slave).exec(0xc20818e540, 0xc2081980c0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:431 +0x160
main.(*Slave).minimizeInput(0xc20818e540, 0xc20818c510, 0x5, 0x8, 0xc20822e201, 0xc208141d30, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:218 +0x4ba
main.(*Slave).processCrasher(0xc20818e540, 0xc20818c510, 0x5, 0x8, 0xc20822a680, 0x349, 0x680, 0xc2087fa080, 0x79, 0x80, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:186 +0x93
main.(*Slave).loop(0xc20818e540)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:75 +0x35f
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 27 [runnable]:
syscall.ByteSliceFromString(0xc208018000, 0xccf, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:51 +0x129
syscall.BytePtrFromString(0xc208018000, 0xccf, 0xc2081b24e0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall.go:65 +0x3e
syscall.SlicePtrFromStrings(0xc20812c000, 0x31, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:85 +0xd9
syscall.forkExec(0x7fff5fbfe66e, 0xd, 0xc2081b2200, 0x1, 0x1, 0xc20813d6f0, 0xc20810c540, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:156 +0x1d3
syscall.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2081b2200, 0x1, 0x1, 0xc20813d6f0, 0x4, 0x8, 0x0, 0x0)
    /Users/antoine/go/src/syscall/exec_unix.go:238 +0x6e
os.startProcess(0x7fff5fbfe66e, 0xd, 0xc2081b2200, 0x1, 0x1, 0xc20813d940, 0xc20812c000, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_posix.go:45 +0x40c
os.StartProcess(0x7fff5fbfe66e, 0xd, 0xc2081b2200, 0x1, 0x1, 0xc20813d940, 0x4, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:24 +0x6c
os/exec.(*Cmd).Start(0xc20821db80, 0x0, 0x0)
    /Users/antoine/go/src/os/exec/exec.go:319 +0x894
main.newTestee(0x7fff5fbfe66e, 0xd, 0xc208093310, 0x46, 0x2e60000, 0x10000, 0x110000, 0x2e70000, 0x100000, 0x100000, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:55 +0x919
main.(*Slave).exec(0xc20818e600, 0xc2081b21e0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:428 +0x10a
main.(*Slave).minimizeInput(0xc20818e600, 0xc2081a2050, 0x2, 0x8, 0xc20822e201, 0xc20813dd30, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:218 +0x4ba
main.(*Slave).processCrasher(0xc20818e600, 0xc2081a2050, 0x2, 0x8, 0xc20814e680, 0x346, 0x680, 0xc2081e6000, 0x79, 0x80, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:186 +0x93
main.(*Slave).loop(0xc20818e600)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:75 +0x35f
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 28 [runnable]:
syscall.Syscall(0x25, 0xd0b3, 0x9, 0x1, 0x0, 0x0, 0x0)
    /Users/antoine/go/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.kill(0xd0b3, 0x9, 0x1, 0x0, 0x0)
    /Users/antoine/go/src/syscall/zsyscall_darwin_amd64.go:286 +0x53
syscall.Kill(0xd0b3, 0x9, 0x0, 0x0)
    /Users/antoine/go/src/syscall/syscall_darwin.go:212 +0x49
os.(*Process).signal(0xc20819a020, 0xa60078, 0xc2080162d0, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_unix.go:53 +0x362
os.(*Process).Signal(0xc20819a020, 0xa60078, 0xc2080162d0, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:51 +0x48
os.(*Process).kill(0xc20819a020, 0x0, 0x0)
    /Users/antoine/go/src/os/exec_posix.go:53 +0x4c
os.(*Process).Kill(0xc20819a020, 0x0, 0x0)
    /Users/antoine/go/src/os/doc.go:36 +0x34
main.(*Testee).shutdown(0xc208122080, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:203 +0xa0
main.(*Slave).exec(0xc20818e6c0, 0xc208016470, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:438 +0x200
main.(*Slave).minimizeInput(0xc20818e6c0, 0xc208016ac0, 0x2, 0x8, 0xc20822e201, 0xc20848bd30, 0x0, 0x0, 0x0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:236 +0x6ec
main.(*Slave).processCrasher(0xc20818e6c0, 0xc208016ac0, 0x2, 0x8, 0xc208150d80, 0x346, 0x680, 0xc2081d2000, 0x79, 0x80, ...)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:186 +0x93
main.(*Slave).loop(0xc20818e6c0)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:75 +0x35f
created by main.slaveMain
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/slave.go:61 +0xe5

goroutine 60581 [select]:
main.newTestee.func3(0xc2087fa700)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:141 +0x15b
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:146 +0xce9

goroutine 60542 [select]:
main.newTestee.func3(0xc208122080)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:141 +0x15b
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:146 +0xce9

goroutine 60597 [runnable]:
main.newTestee.func2(0xc208216b00)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:117
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:138 +0xcc6

goroutine 60579 [runnable]:
main.newTestee.func1(0xc2087fa700)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:91 +0x5e
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:115 +0xca3

goroutine 60541 [select]:
main.newTestee.func2(0xc208122080)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:121 +0x32c
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:138 +0xcc6

goroutine 60580 [runnable]:
main.newTestee.func2(0xc2087fa700)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:117
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:138 +0xcc6

goroutine 60596 [runnable]:
main.newTestee.func1(0xc208216b00)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:83
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:115 +0xca3

goroutine 60598 [select]:
main.newTestee.func3(0xc208216b00)
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:141 +0x15b
created by main.newTestee
    /Users/antoine/cthulhu/third_party/src/github.com/dvyukov/go-fuzz/go-fuzz/testee.go:146 +0xce9

instrumentation fails for large constants

Instrumentation of the following code fails as follows:

const X = 1<<129

func foo(x float64) bool {
    return x < X
}
test.go:15: constant 680564733841876926926749214863536422912 overflows int

coverprofile does not include package path

Using gofuzz's GIT tip (2a8f663) with the -dumpcover flag produces a coverprofile file like the following (truncated):

mode: set
strings.go:378.4,379.1 0 0
decimal.go:96.23,99.3 2 0
ycbcr.go:114.3,115.1 0 0
nextafter.go:41.2,42.38 1 0
pipe.go:91.3,91.20 1 0
reader.go:325.31,329.26 2 0
ftoa.go:158.2,158.30 1 0
atof.go:491.4,492.76 2 0
read.go:189.4,190.1 0 1
decimal.go:69.15,72.3 2 0
image.go:319.2,323.18 5 0
float.go:804.16,806.3 1 0
image.go:998.47,999.34 1 0
utf8.go:303.2,303.37 1 1
extfloat.go:235.41,251.2 9 1
natconv.go:291.5,300.5 5 0
rand.go:176.22,176.52 1 0
float.go:232.16,234.3 1 0
scan.go:498.13,500.4 1 0
public_key_v3.go:238.3,239.1 0 0
binary.go:314.2,318.12 5 0
quote.go:317.18,318.23 1 0
j1.go:115.4,116.1 0 0
float.go:806.3,807.1 0 0
letter.go:275.27,277.4 1 0
atof.go:412.2,413.17 1 0
private_key.go:262.2,266.43 5 1
image.go:1006.18,1007.12 1 0
public_key.go:242.3,243.41 2 1
quote.go:49.3,50.30 1 0
natconv.go:224.13,227.3 1 0
huffman_bit_writer.go:407.2,407.21 1 0
common.go:116.18,119.5 2 0
signature.go:223.4,224.1 0 1

As you can see, this instrumentation does not include the package path so the coverage profile cannot be analyzed.

panic: runtime error: index out of range (versifier)

Running goroutine stack trace:

$ go-fuzz -workdir=fuzz -bin=securecookie-fuzz.zip 
2015/08/18 11:44:35 slaves: 4, corpus: 100 (3s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s
2015/08/18 11:44:38 slaves: 4, corpus: 100 (6s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 6s
2015/08/18 11:44:41 slaves: 4, corpus: 100 (9s ago), crashers: 0, restarts: 1/6771, execs: 54173 (5953/sec), cover: 0, uptime: 9s
2015/08/18 11:44:44 slaves: 4, corpus: 100 (12s ago), crashers: 0, restarts: 1/8801, execs: 105620 (8756/sec), cover: 0, uptime: 12s
panic: runtime error: index out of range

goroutine 31 [running]:
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structureKeyValue(0xc8203f6a80, 0x4, 0x4, 0x0, 0x0, 0x0)
    /Users/kamil/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:695 +0x4a7
github.com/dvyukov/go-fuzz/go-fuzz/versifier.structure(0xc8203f6a80, 0x4, 0x4, 0x0, 0x0, 0x0)
    /Users/kamil/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:575 +0xdd
github.com/dvyukov/go-fuzz/go-fuzz/versifier.BuildVerse(0x0, 0xc82008ba20, 0x14c, 0x14c, 0x10000)
    /Users/kamil/src/github.com/dvyukov/go-fuzz/go-fuzz/versifier/versifier.go:55 +0x1b9
main.(*Hub).loop(0xc8200b0a00)
    /Users/kamil/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:236 +0x1c2c
created by main.newHub
    /Users/kamil/src/github.com/dvyukov/go-fuzz/go-fuzz/hub.go:115 +0xe83

Complete trace is here:
https://gist.github.com/kisielk/b3faaf4cbde1a5d026db

Frequent restarts

My output looks like this:

[jweiss@localhost fuzz]$ go-fuzz -bin=./fuzz-fuzz -corpus=corpus -workdir=./work
2015/05/26 06:50:47 slaves: 8, corpus: 3 (1s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 0.00%, uptime: 3s
2015/05/26 06:50:50 slaves: 8, corpus: 3 (4s ago), crashers: 1, restarts: 1/0, execs: 0 (0/sec), cover: 2.88%, uptime: 6s
2015/05/26 06:50:53 slaves: 8, corpus: 3 (7s ago), crashers: 1, restarts: 1/2, execs: 3762 (418/sec), cover: 2.88%, uptime: 9s
2015/05/26 06:50:56 slaves: 8, corpus: 7 (0s ago), crashers: 1, restarts: 1/1, execs: 5824 (485/sec), cover: 2.88%, uptime: 12s
2015/05/26 06:50:59 slaves: 8, corpus: 8 (2s ago), crashers: 1, restarts: 1/1, execs: 7867 (524/sec), cover: 3.01%, uptime: 15s
2015/05/26 06:51:02 slaves: 8, corpus: 8 (5s ago), crashers: 1, restarts: 1/1, execs: 13276 (738/sec), cover: 3.03%, uptime: 18s
2015/05/26 06:51:05 slaves: 8, corpus: 8 (8s ago), crashers: 1, restarts: 1/2, execs: 17609 (838/sec), cover: 3.03%, uptime: 21s
2015/05/26 06:51:08 slaves: 8, corpus: 8 (11s ago), crashers: 1, restarts: 1/2, execs: 20109 (838/sec), cover: 3.03%, uptime: 24s
2015/05/26 06:51:11 slaves: 8, corpus: 8 (14s ago), crashers: 1, restarts: 1/2, execs: 23696 (878/sec), cover: 3.03%, uptime: 27s
2015/05/26 06:51:14 slaves: 8, corpus: 8 (17s ago), crashers: 1, restarts: 1/2, execs: 28550 (952/sec), cover: 3.03%, uptime: 30s
2015/05/26 06:51:17 slaves: 8, corpus: 8 (20s ago), crashers: 1, restarts: 1/2, execs: 31179 (945/sec), cover: 3.03%, uptime: 33s
2015/05/26 06:51:20 slaves: 8, corpus: 8 (23s ago), crashers: 1, restarts: 1/3, execs: 32948 (915/sec), cover: 3.03%, uptime: 36s
2015/05/26 06:51:23 slaves: 8, corpus: 8 (26s ago), crashers: 1, restarts: 1/3, execs: 35817 (918/sec), cover: 3.03%, uptime: 39s
2015/05/26 06:51:26 slaves: 8, corpus: 8 (29s ago), crashers: 1, restarts: 1/3, execs: 38258 (911/sec), cover: 3.03%, uptime: 42s
2015/05/26 06:51:29 slaves: 8, corpus: 8 (32s ago), crashers: 1, restarts: 1/3, execs: 40804 (907/sec), cover: 3.03%, uptime: 45s
2015/05/26 06:51:32 slaves: 8, corpus: 8 (35s ago), crashers: 1, restarts: 1/3, execs: 43294 (902/sec), cover: 3.03%, uptime: 48s
2015/05/26 06:51:35 slaves: 8, corpus: 8 (38s ago), crashers: 1, restarts: 1/4, execs: 45034 (883/sec), cover: 3.03%, uptime: 51s
2015/05/26 06:51:38 slaves: 8, corpus: 8 (41s ago), crashers: 1, restarts: 1/4, execs: 45192 (837/sec), cover: 3.03%, uptime: 54s
2015/05/26 06:51:41 slaves: 8, corpus: 8 (44s ago), crashers: 1, restarts: 1/4, execs: 45317 (795/sec), cover: 3.03%, uptime: 57s
2015/05/26 06:51:44 slaves: 8, corpus: 8 (47s ago), crashers: 1, restarts: 1/4, execs: 45960 (766/sec), cover: 3.03%, uptime: 1m0s
2015/05/26 06:51:47 slaves: 8, corpus: 8 (50s ago), crashers: 1, restarts: 1/4, execs: 46377 (736/sec), cover: 3.03%, uptime: 1m3s
2015/05/26 06:51:50 slaves: 8, corpus: 8 (53s ago), crashers: 1, restarts: 1/4, execs: 46663 (707/sec), cover: 3.03%, uptime: 1m6s

The slowness is an obvious problem, but what I don't understand is why it is restarting so frequently. Only one input caused a crash, so why does it have to restart every 4 executions? As the test goes on, the ratio improves but not much (after 20 minutes it's 1/53). If I look at my process list over time, each one seems to live for about 5-10 seconds.

I don't know where I can get more debugging information. I can't print anything to stdout because it's not captured anywhere. Can the reason for restart be output somewhere?

One thing that would be "nice to have" is a distribution of "interestingness" scores,eg:

interestingness: 0: 1207, 1: 75, 2: 12

Also I notice there is a "work/suppressions" directory that is not described in the README. What is that? Seems like some stdout goes there but not sure what makes it there and what doesn't.

Finally, the corpus increases to 8 after two seconds, and 20 minutes later, it's the exact same 8 items in the corpus. Is that normal?

go-fuzz-build fails

I am able to run the examples successfully (I tried json).

However if I try to fuzz my own project, go-fuzz-build fails immediately with a build error that doesn't occur with the normal go toolset (go 1.4) in my project.

[jweiss@localhost gotary]$ go-fuzz-build github.com/monetas/gotary/processing/fuzz
failed to execute go build: exit status 2
# github.com/monetas/gotary/database
database/database.go:95: undefined: types.NymState
database/database.go:97: undefined: types.NymState

Examining my source, those two errors shouldn't happen. The types package is imported properly at the top of the file, NymState is in a file in that package, and there are other references to the types package earlier in the database.go file that do not cause complaints.

I tried keeping the go-fuzz-build tmp dir, and examining its contents, but there's just a trivial main.go file there and nothing else.

package main

import (
    target "github.com/monetas/gotary/processing/fuzz"
    dep "github.com/dvyukov/go-fuzz/go-fuzz-dep"
)

func main() {
    dep.Main(target.Fuzz, lits)
}

var lits = []string{

}

I am guessing something must go wrong with copying or building somehow but I'm not sure what to do from here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.