From e5247f7886aad90d6fa402b5308d4c30afdfebdf Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Wed, 25 Aug 2021 13:31:19 -0700 Subject: [dev.fuzz] internal/fuzz: don't store corpus in memory Instead of holding all corpus data/values in memory, only store seed inputs added via F.Add in memory, and only load corpus entries which are written to disk when we need them. This should significantly reduce the memory required by the coordinator process. Additionally only load the corpus in the coordinator process, since the worker has no need for it. Fixes #46669. Change-Id: Ic3b0c5e929fdb3e2877b963e6b0fa14e140c1e1d Reviewed-on: https://go-review.googlesource.com/c/go/+/345096 Trust: Roland Shoemaker Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Reviewed-by: Jay Conrod --- src/testing/fuzz.go | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/testing') diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index 4892d3f3e9..e567f7d9f4 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -305,21 +305,33 @@ func (f *F) Fuzz(ff interface{}) { types = append(types, t) } - // Check the corpus provided by f.Add - for _, c := range f.corpus { - if err := f.fuzzContext.checkCorpus(c.Values, types); err != nil { - // TODO: Is there a way to save which line number is associated - // with the f.Add call that failed? + // Only load the corpus if we need it + if f.fuzzContext.runFuzzWorker == nil { + // Check the corpus provided by f.Add + for _, c := range f.corpus { + if err := f.fuzzContext.checkCorpus(c.Values, types); err != nil { + // TODO: Is there a way to save which line number is associated + // with the f.Add call that failed? + f.Fatal(err) + } + } + + // Load seed corpus + c, err := f.fuzzContext.readCorpus(filepath.Join(corpusDir, f.name), types) + if err != nil { f.Fatal(err) } - } - // Load seed corpus - c, err := f.fuzzContext.readCorpus(filepath.Join(corpusDir, f.name), types) - if err != nil { - f.Fatal(err) + // If this is the coordinator process, zero the values, since we don't need to hold + // onto them. + if f.fuzzContext.coordinateFuzzing != nil { + for i := range c { + c[i].Values = nil + } + } + + f.corpus = append(f.corpus, c...) } - f.corpus = append(f.corpus, c...) // run calls fn on a given input, as a subtest with its own T. // run is analogous to T.Run. The test filtering and cleanup works similarly. -- cgit v1.3-5-g9baa