Open stevenjohnstone opened 3 years ago
With change https://github.com/golang/go/pull/48292 I see a 25% reduction in work done by the fuzzer when the signature of the function under test is
func(t *testing.T, b []byte, on bool)
Change https://golang.org/cl/348849 mentions this issue: [dev.fuzz] internal/fuzz: always perform logical not on booleans when…
The int mutators are actually really interesting from a mathematical point of view. They are random walks with non-local conditions (the probability of a jump depends on the distance from the extreme points of the integer). This gives quite strange probability distributions. Here's what a sample of the distribution (starting a zero) looks like for uint8 (forgive the gnuplot purple):
uin32 looks like a slow shuffle relatively close to zero but eventually it'd probably look something like uint8
The mutator is here:
Some properties of the mutator which are undesirable:
numIters
> 1numIters
could be large with low probability)maxValue
, 50% of the iterations do nothing and the loop repeatsA more straight forward way to mutate an int would be to pick a random bit and flip it. That gives a uniform distribution of values, will never leave the integer unchanged and probably be good for things like flags.
I think I just ran into this bug. I wrote a test function that panics if an input int
is > 5000
. Without any corpus (e.g. calls to f.Add
), it won't find this "bug" within 60 seconds on my machine, which reported approximately 30M executions. This surprises me. This shouldn't be hard to find.
I found two workarounds that work for me:
f.Add
by calling it with a range of integers (e.g. every 500 or something?). This works if the seeds are "close" to the trigger values.[]byte
argument and convert it to an integer. This seems to work very well for values close to 0. For example, this even finds arg == 12345
very quickly, but does not find arg == 12345679
See https://github.com/evanj/gofuzztesting for a reproduction
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
n/a
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Ran this fuzz test:
I have a bpftrace script:
Using that during runs of FuzzInt etc I can see that I get successive inputs to the fuzzer which are the same. For the boolean it's ~50% of the time, for uint8 about 0.3% and the rest 0.2%. I was taking a look because I had a test with this signature
and I'd see about 1/4 of the time it was executing the same test case as the previous run.
What did you expect to see?
I'd expect a mutation of a boolean to just flip the value true->false, false->true. There's no need for anything probabilistic here. For the ints, it's not as obvious of a problem but if my test signature was
the fuzzer would be doing the same work twice ~0.1% of the time. Not a massive amount but multiplied over all golang CIs, it's significant. My attempt at keeping CO2 in the ground :sweat_smile:
What did you see instead?
Mutations which are no-ops.