aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-05-16 13:41:53 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-05-16 15:38:27 +0000
commit2f25d0f441166a6b106eba49d9a256eb825b644b (patch)
tree5153451c46ebd003991f2d4c06d8cb2f594dc4d9 /pkg
parent19e202fa8a3722f5c90ed5847edb5aeabdd5f38f (diff)
pkg/fuzzer: simplify prog execution options
For now, only ProgTypes is enough.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/fuzzer/fuzzer.go37
-rw-r--r--pkg/fuzzer/job.go11
-rw-r--r--pkg/fuzzer/job_test.go4
3 files changed, 22 insertions, 30 deletions
diff --git a/pkg/fuzzer/fuzzer.go b/pkg/fuzzer/fuzzer.go
index 10056b528..bdcfeb2fb 100644
--- a/pkg/fuzzer/fuzzer.go
+++ b/pkg/fuzzer/fuzzer.go
@@ -92,45 +92,36 @@ func newExecQueues(fuzzer *Fuzzer) execQueues {
return ret
}
-type execOpt any
-type dontTriage struct{}
-type progFlags ProgTypes
+func (fuzzer *Fuzzer) execute(executor queue.Executor, req *queue.Request) *queue.Result {
+ return fuzzer.executeWithFlags(executor, req, 0)
+}
-func (fuzzer *Fuzzer) execute(executor queue.Executor, req *queue.Request, opts ...execOpt) *queue.Result {
+func (fuzzer *Fuzzer) executeWithFlags(executor queue.Executor, req *queue.Request, flags ProgTypes) *queue.Result {
executor.Submit(req)
res := req.Wait(fuzzer.ctx)
- fuzzer.processResult(req, res, opts...)
+ fuzzer.processResult(req, res, flags)
return res
}
-func (fuzzer *Fuzzer) prepare(req *queue.Request, opts ...execOpt) {
+func (fuzzer *Fuzzer) prepare(req *queue.Request, flags ProgTypes) {
req.OnDone(func(req *queue.Request, res *queue.Result) bool {
- fuzzer.processResult(req, res, opts...)
+ fuzzer.processResult(req, res, flags)
return true
})
}
-func (fuzzer *Fuzzer) enqueue(executor queue.Executor, req *queue.Request, opts ...execOpt) {
- fuzzer.prepare(req, opts...)
+func (fuzzer *Fuzzer) enqueue(executor queue.Executor, req *queue.Request, flags ProgTypes) {
+ fuzzer.prepare(req, flags)
executor.Submit(req)
}
-func (fuzzer *Fuzzer) processResult(req *queue.Request, res *queue.Result, opts ...execOpt) {
- var flags ProgTypes
- var noTriage bool
- for _, opt := range opts {
- switch v := opt.(type) {
- case progFlags:
- flags = ProgTypes(v)
- case dontTriage:
- noTriage = true
- }
- }
+func (fuzzer *Fuzzer) processResult(req *queue.Request, res *queue.Result, flags ProgTypes) {
+ inTriage := flags&progInTriage > 0
// Triage individual calls.
// We do it before unblocking the waiting threads because
// it may result it concurrent modification of req.Prog.
// If we are already triaging this exact prog, this is flaky coverage.
- if req.ExecOpts.ExecFlags&ipc.FlagCollectSignal > 0 && res.Info != nil && !noTriage {
+ if req.ExecOpts.ExecFlags&ipc.FlagCollectSignal > 0 && res.Info != nil && !inTriage {
for call, info := range res.Info.Calls {
fuzzer.triageProgCall(req.Prog, &info, call, flags)
}
@@ -210,7 +201,7 @@ func (fuzzer *Fuzzer) genFuzz() *queue.Request {
if req == nil {
req = genProgRequest(fuzzer, rnd)
}
- fuzzer.prepare(req)
+ fuzzer.prepare(req, 0)
return req
}
@@ -251,7 +242,7 @@ type Candidate struct {
func (fuzzer *Fuzzer) AddCandidates(candidates []Candidate) {
for _, candidate := range candidates {
req, flags := candidateRequest(fuzzer, candidate)
- fuzzer.enqueue(fuzzer.candidateQueue, req, progFlags(flags))
+ fuzzer.enqueue(fuzzer.candidateQueue, req, flags)
}
}
diff --git a/pkg/fuzzer/job.go b/pkg/fuzzer/job.go
index 2ec415bdb..174acdc52 100644
--- a/pkg/fuzzer/job.go
+++ b/pkg/fuzzer/job.go
@@ -26,6 +26,7 @@ const (
progCandidate ProgTypes = 1 << iota
progMinimized
progSmashed
+ progInTriage
)
func genProgRequest(fuzzer *Fuzzer, rnd *rand.Rand) *queue.Request {
@@ -88,9 +89,9 @@ type triageJob struct {
queue queue.Executor
}
-func (job *triageJob) execute(req *queue.Request, opts ...execOpt) *queue.Result {
+func (job *triageJob) execute(req *queue.Request, flags ProgTypes) *queue.Result {
req.Important = true // All triage executions are important.
- return job.fuzzer.execute(job.queue, req, opts...)
+ return job.fuzzer.executeWithFlags(job.queue, req, flags)
}
func (job *triageJob) run(fuzzer *Fuzzer) {
@@ -138,7 +139,7 @@ type deflakedCover struct {
rawCover []uint32
}
-func (job *triageJob) deflake(exec func(*queue.Request, ...execOpt) *queue.Result, stat *stats.Val,
+func (job *triageJob) deflake(exec func(*queue.Request, ProgTypes) *queue.Result, stat *stats.Val,
rawCover bool) (info deflakedCover, stop bool) {
// As demonstrated in #4639, programs reproduce with a very high, but not 100% probability.
// The triage algorithm must tolerate this, so let's pick the signal that is common
@@ -165,7 +166,7 @@ func (job *triageJob) deflake(exec func(*queue.Request, ...execOpt) *queue.Resul
ExecOpts: setFlags(ipc.FlagCollectCover | ipc.FlagCollectSignal),
ReturnAllSignal: true,
Stat: stat,
- }, &dontTriage{})
+ }, progInTriage)
if result.Stop() {
stop = true
return
@@ -205,7 +206,7 @@ func (job *triageJob) minimize(newSignal signal.Signal) (stop bool) {
SignalFilter: newSignal,
SignalFilterCall: call1,
Stat: job.fuzzer.statExecMinimize,
- })
+ }, 0)
if result.Stop() {
stop = true
return false
diff --git a/pkg/fuzzer/job_test.go b/pkg/fuzzer/job_test.go
index 59f0e7097..b7718134b 100644
--- a/pkg/fuzzer/job_test.go
+++ b/pkg/fuzzer/job_test.go
@@ -29,7 +29,7 @@ func TestDeflakeFail(t *testing.T) {
}
run := 0
- ret, stop := testJob.deflake(func(_ *queue.Request, _ ...execOpt) *queue.Result {
+ ret, stop := testJob.deflake(func(_ *queue.Request, _ ProgTypes) *queue.Result {
run++
// For first, we return 0 and 1. For second, 1 and 2. And so on.
return fakeResult(0, []uint32{uint32(run), uint32(run + 1)}, []uint32{10, 20})
@@ -54,7 +54,7 @@ func TestDeflakeSuccess(t *testing.T) {
newSignal: signal.FromRaw([]uint32{0, 1, 2}, 0),
}
run := 0
- ret, stop := testJob.deflake(func(_ *queue.Request, _ ...execOpt) *queue.Result {
+ ret, stop := testJob.deflake(func(_ *queue.Request, _ ProgTypes) *queue.Result {
run++
switch run {
case 1: