Skip to content

Commit

Permalink
Add --cfg fuzzing_repro when reproducing a crash
Browse files Browse the repository at this point in the history
This makes it possible to leave large or expensive debug output in
your fuzzers since it will only be active when you reproduce a crash:

    #[cfg(fuzzing_repro)]
    eprintln!("Expensive debug output: {}", do_something_expensive());

Fixes rust-fuzz#343.
  • Loading branch information
mgeisler committed Jun 16, 2023
1 parent abb7a67 commit 08c23e0
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ pub struct BuildOptions {
#[arg(long)]
pub no_cfg_fuzzing: bool,

#[arg(skip = false)]
/// Add the 'cfg(fuzzing-repro)' compilation configuration. This build
/// option will be automatically used when running `cargo fuzz run <target>
/// <corpus>`. The option will not be shown to the user, which is ensured by
/// the `skip` attribute.
pub cfg_fuzzing_repro: bool,

#[arg(long)]
/// Don't build with the `sanitizer-coverage-trace-compares` LLVM argument
///
Expand Down Expand Up @@ -232,6 +239,7 @@ mod test {
coverage: false,
strip_dead_code: false,
no_cfg_fuzzing: false,
cfg_fuzzing_repro: false,
no_trace_compares: false,
};

Expand Down
1 change: 1 addition & 0 deletions src/options/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct Run {
impl RunCommand for Run {
fn run_command(&mut self) -> Result<()> {
let project = FuzzProject::new(self.fuzz_dir_wrapper.fuzz_dir.to_owned())?;
self.build.cfg_fuzzing_repro = !self.corpus.is_empty();
project.exec_fuzz(self)
}
}
4 changes: 4 additions & 0 deletions src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ impl FuzzProject {
rustflags.push_str(" --cfg fuzzing");
}

if build.cfg_fuzzing_repro {
rustflags.push_str(" --cfg fuzzing_repro");
}

if !build.strip_dead_code {
rustflags.push_str(" -Clink-dead-code");
}
Expand Down
19 changes: 15 additions & 4 deletions tests/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ fn run_no_crash() {
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
#[cfg(fuzzing_repro)]
eprintln!("Reproducing a crash");
run_no_crash::pass_fuzzing(data);
});
"#,
Expand All @@ -188,7 +191,10 @@ fn run_no_crash() {
.arg("--")
.arg("-runs=1000")
.assert()
.stderr(predicate::str::contains("Done 1000 runs"))
.stderr(
predicate::str::contains("Done 1000 runs")
.and(predicate::str::contains("Reproducing a crash").not()),
)
.success();
}

Expand Down Expand Up @@ -429,6 +435,9 @@ fn run_one_input() {
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
#[cfg(fuzzing_repro)]
eprintln!("Reproducing a crash");
assert!(data.is_empty());
});
"#,
Expand All @@ -444,9 +453,11 @@ fn run_one_input() {
.arg(corpus.join("pass"))
.assert()
.stderr(
predicate::str::contains("Running 1 inputs 1 time(s) each.").and(
predicate::str::contains("Running: fuzz/corpus/run_one/pass"),
),
predicate::str::contains("Running 1 inputs 1 time(s) each.")
.and(predicate::str::contains(
"Running: fuzz/corpus/run_one/pass",
))
.and(predicate::str::contains("Reproducing a crash")),
)
.success();
}
Expand Down

0 comments on commit 08c23e0

Please sign in to comment.