aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/fuzzer
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-11-19 16:42:32 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-11-20 11:33:58 +0000
commitf56b4dcc82d7af38bf94d643c5750cf49a91a297 (patch)
tree19b2ea6bfcbf61ab7287d420f39c45432bd9b4cc /pkg/fuzzer
parent7d02db5adbb376babbbd3199f8c530e468292727 (diff)
pkg/manager: show number of times coverage for each call has overflowed
If the overflows happen often, it's bad. Add visibility into this.
Diffstat (limited to 'pkg/fuzzer')
-rw-r--r--pkg/fuzzer/fuzzer.go22
-rw-r--r--pkg/fuzzer/stats.go20
2 files changed, 39 insertions, 3 deletions
diff --git a/pkg/fuzzer/fuzzer.go b/pkg/fuzzer/fuzzer.go
index 3dac022ad..3e5f94fc3 100644
--- a/pkg/fuzzer/fuzzer.go
+++ b/pkg/fuzzer/fuzzer.go
@@ -50,7 +50,7 @@ func NewFuzzer(ctx context.Context, cfg *Config, rnd *rand.Rand,
}
}
f := &Fuzzer{
- Stats: newStats(),
+ Stats: newStats(target),
Config: cfg,
Cover: newCover(),
@@ -170,6 +170,10 @@ func (fuzzer *Fuzzer) processResult(req *queue.Request, res *queue.Result, flags
if res.Info != nil {
fuzzer.statExecTime.Add(int(res.Info.Elapsed / 1e6))
+ for call, info := range res.Info.Calls {
+ fuzzer.handleCallInfo(req, info, call)
+ }
+ fuzzer.handleCallInfo(req, res.Info.Extra, -1)
}
// Corpus candidates may have flaky coverage, so we give them a second chance.
@@ -231,6 +235,22 @@ func (fuzzer *Fuzzer) triageProgCall(p *prog.Prog, info *flatrpc.CallInfo, call
}
}
+func (fuzzer *Fuzzer) handleCallInfo(req *queue.Request, info *flatrpc.CallInfo, call int) {
+ if info == nil || info.Flags&flatrpc.CallFlagCoverageOverflow == 0 {
+ return
+ }
+ syscallIdx := len(fuzzer.Syscalls) - 1
+ if call != -1 {
+ syscallIdx = req.Prog.Calls[call].Meta.ID
+ }
+ stat := &fuzzer.Syscalls[syscallIdx]
+ if req.ExecOpts.ExecFlags&flatrpc.ExecFlagCollectComps != 0 {
+ stat.CompsOverflows.Add(1)
+ } else {
+ stat.CoverOverflows.Add(1)
+ }
+}
+
func signalPrio(p *prog.Prog, info *flatrpc.CallInfo, call int) (prio uint8) {
if call == -1 {
return 0
diff --git a/pkg/fuzzer/stats.go b/pkg/fuzzer/stats.go
index 7990f8b13..40c71d309 100644
--- a/pkg/fuzzer/stats.go
+++ b/pkg/fuzzer/stats.go
@@ -3,9 +3,17 @@
package fuzzer
-import "github.com/google/syzkaller/pkg/stat"
+import (
+ "sync/atomic"
+
+ "github.com/google/syzkaller/pkg/stat"
+ "github.com/google/syzkaller/prog"
+)
type Stats struct {
+ // Indexed by prog.Syscall.ID + the last element for extra/remote.
+ Syscalls []SyscallStats
+
statCandidates *stat.Val
statNewInputs *stat.Val
statJobs *stat.Val
@@ -27,8 +35,16 @@ type Stats struct {
statExecCollide *stat.Val
}
-func newStats() Stats {
+type SyscallStats struct {
+ // Number of times coverage buffer for this syscall has overflowed.
+ CoverOverflows atomic.Uint64
+ // Number of times comparisons buffer for this syscall has overflowed.
+ CompsOverflows atomic.Uint64
+}
+
+func newStats(target *prog.Target) Stats {
return Stats{
+ Syscalls: make([]SyscallStats, len(target.Syscalls)+1),
statCandidates: stat.New("candidates", "Number of candidate programs in triage queue",
stat.Console, stat.Graph("corpus")),
statNewInputs: stat.New("new inputs", "Potential untriaged corpus candidates",