Skip to content

Add --exit_on_time and --exit_on_time_min_runs to stop a run once coverage plateaus - #1067

Open
sigdevel wants to merge 4 commits into
CodeIntelligenceTesting:mainfrom
sigdevel:main
Open

sigdevel wants to merge 4 commits into
CodeIntelligenceTesting:mainfrom
sigdevel:main

Conversation

@sigdevel

@sigdevel sigdevel commented Oct 7, 2026

Copy link
Copy Markdown

Motivation

Jazzer can bound a run by wall-clock time (--max_duration) or by executions
(--max_executions), but both budgets are fixed up front: a campaign either gets
cut off while it is still finding new coverage, or keeps burning CPU long after
the corpus has saturated. The natural stopping signal - no new coverage features
for a while - has no flag in libFuzzer, so it currently has to be reimplemented
outside Jazzer by parsing the log or polling the corpus directory.

What this adds

  • --exit_on_time=<seconds> - exit successfully if no new coverage features are
    discovered for that many seconds. 0 (default) disables it. Single-process
    fuzzing only; rejected together with -fork, -jobs, -merge and
    -set_cover_merge.
  • --exit_on_time_min_runs=<N> - minimum executions before --exit_on_time may
    fire (default 100000), so a slow-starting target is not killed during warm-up.

Both go through the usual Jazzer configuration sources and work in the standalone
driver and the JUnit integration. A native -exit_on_time flag takes precedence
over the Jazzer option, mirroring -max_total_time vs --max_duration. Values
above 2147483647 are rejected rather than silently truncated into libFuzzer's
int flags.

Implementation

libFuzzer does not track when coverage last grew, so this needs a small change
there: two flags, two option fields, one timestamp updated in RunOne, one break
condition in Loop(), plus flag validation. It is applied to the
jazzer_libfuzzer archive as third_party/libfuzzer-exit-on-time.patch,
following the existing jazzer_jacoco patches in MODULE.bazel. Happy to move
it into CodeIntelligenceTesting/llvm-project-jazzer and bump the archive tag
instead if you prefer that route.

Tests

DriverTest covers the flag translation (default and explicit min_runs,
--exit_on_time=0, min_runs without exit_on_time, native-flag precedence,
out-of-range values). ExitOnTimeFuzzer adds integration targets for the native
flags, the Jazzer options, the min_runs gate and flag precedence; it asserts its
own run duration in fuzzerTearDown to tell an -exit_on_time exit apart from a
-max_total_time one.

Docs: docs/arguments-and-configuration-options.md and a "Stopping criteria"
section in README.md.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant