From a9c35b135ecf61a55699d424ac2aaf507a30192c Mon Sep 17 00:00:00 2001 From: Xinhao Yuan Date: Mon, 16 Dec 2024 16:06:31 -0800 Subject: [PATCH] Always call `CentipedeFinalizeProcessing` to report FuzzTest input properly. This is needed because otherwise Centipede would crash for exceeded memory/time limits after FuzzTest cleaning up the current input, leading to undesired "setup failure" reports. But we don't want Centipede to prepare the coverage twice (which would result in garbage coverage). Thus using the input_start_time as a guard - they should be set to 0 after each iteration anyway. PiperOrigin-RevId: 706865286 --- centipede/runner.cc | 8 ++++++-- centipede/runner_interface.h | 3 +++ fuzztest/internal/centipede_adaptor.cc | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/centipede/runner.cc b/centipede/runner.cc index 31950352..e5714a03 100644 --- a/centipede/runner.cc +++ b/centipede/runner.cc @@ -614,7 +614,9 @@ static void RunOneInput(const uint8_t *data, size_t size, int target_return_value = callbacks.Execute({data, size}) ? 0 : -1; state.stats.exec_time_usec = UsecSinceLast(); CheckWatchdogLimits(); - PostProcessCoverage(target_return_value); + if (centipede::state.input_start_time.exchange(0) != 0) { + PostProcessCoverage(target_return_value); + } state.stats.post_time_usec = UsecSinceLast(); state.stats.peak_rss_mb = GetPeakRSSMb(); } @@ -1235,7 +1237,9 @@ extern "C" void CentipedePrepareProcessing() { extern "C" void CentipedeFinalizeProcessing() { centipede::CheckWatchdogLimits(); - centipede::PostProcessCoverage(/*target_return_value=*/0); + if (centipede::state.input_start_time.exchange(0) != 0) { + centipede::PostProcessCoverage(/*target_return_value=*/0); + } } extern "C" size_t CentipedeGetExecutionResult(uint8_t *data, size_t capacity) { diff --git a/centipede/runner_interface.h b/centipede/runner_interface.h index 3227cc47..7fd75811 100644 --- a/centipede/runner_interface.h +++ b/centipede/runner_interface.h @@ -103,6 +103,9 @@ extern "C" void CentipedeEndExecutionBatch(); extern "C" void CentipedePrepareProcessing(); // Finalizes the processing of an input and stores the state internally. +// +// For tool integration, it can be called inside `RunnerCallbacks::Execute()` to +// finalize the execution early before extra cleanups. extern "C" void CentipedeFinalizeProcessing(); // Retrieves the execution results (including coverage information) after diff --git a/fuzztest/internal/centipede_adaptor.cc b/fuzztest/internal/centipede_adaptor.cc index 292e450c..c8a0e46a 100644 --- a/fuzztest/internal/centipede_adaptor.cc +++ b/fuzztest/internal/centipede_adaptor.cc @@ -479,7 +479,7 @@ class CentipedeFixtureDriver : public UntypedFixtureDriver { if (runtime_.skipping_requested()) { CentipedeSetExecutionResult(nullptr, 0); } - if (!runner_mode) CentipedeFinalizeProcessing(); + CentipedeFinalizeProcessing(); } void TearDownFuzzTest() override { orig_fixture_driver_->TearDownFuzzTest(); }