@@ -422,6 +422,19 @@ class CentipedeAdaptorRunnerCallbacks
422
422
prng_(GetRandomSeed()) {}
423
423
424
424
bool Execute (fuzztest::internal::ByteSpan input) override {
425
+ [[maybe_unused]] static bool check_if_not_skipped_on_setup = [&] {
426
+ if (runtime_.skipping_requested ()) {
427
+ absl::FPrintF (GetStderr (),
428
+ " [.] Skipping %s per request from the test setup.\n " ,
429
+ fuzzer_impl_.test_ .full_name ());
430
+ CentipedeSetFailureDescription (" SKIPPED TEST: Requested from setup" );
431
+ // It has to use _Exit(1) to avoid trigger the reporting of regular
432
+ // setup failure while let Centipede be aware of this. Note that this
433
+ // skips the fixture teardown.
434
+ std::_Exit (1 );
435
+ }
436
+ return true ;
437
+ }();
425
438
// We should avoid doing anything other than executing the input here so
426
439
// that we don't affect the execution time.
427
440
auto parsed_input =
@@ -728,17 +741,9 @@ bool CentipedeFuzzerAdaptor::Run(int* argc, char*** argv, RunMode mode,
728
741
configuration.replay_in_single_process ) {
729
742
return ReplayCrashInSingleProcess (configuration);
730
743
}
731
- int result = EXIT_FAILURE;
732
- bool to_run_controller = false ;
733
- fuzzer_impl_.fixture_driver_ ->RunFuzzTest ([&, this ]() {
734
- if (runtime_.skipping_requested ()) {
735
- absl::FPrintF (GetStderr (),
736
- " [.] Skipping %s per request from the test setup.\n " ,
737
- test_.full_name ());
738
- result = 0 ;
739
- return ;
740
- }
741
- if (runner_mode) {
744
+ if (runner_mode) {
745
+ std::optional<int > result;
746
+ fuzzer_impl_.fixture_driver_ ->RunFuzzTest ([&, this ]() {
742
747
CentipedeAdaptorRunnerCallbacks runner_callbacks (&runtime_, &fuzzer_impl_,
743
748
&configuration);
744
749
static char fake_argv0[] = " fake_argv" ;
@@ -747,21 +752,33 @@ bool CentipedeFuzzerAdaptor::Run(int* argc, char*** argv, RunMode mode,
747
752
argc != nullptr ? *argc : 1 , argv != nullptr ? *argv : fake_argv,
748
753
runner_callbacks);
749
754
return ;
750
- }
751
- // Centipede engine does not support replay and reproducer minimization
752
- // (within the single process). So use the existing fuzztest implementation.
755
+ });
756
+ FUZZTEST_INTERNAL_CHECK (result.has_value (),
757
+ " No result is set for running fuzz test" );
758
+ return *result == EXIT_SUCCESS;
759
+ } else if (is_running_property_function_in_this_process) {
760
+ // If `is_running_property_function_in_this_process` holds at this point. We
761
+ // assume it is for `ReplayInputsIfAvailable` to handle `FUZZTEST_REPLAY`
762
+ // and `FUZZTEST_MINIMIZE_REPRODUCER`, which Centipede does not support.
753
763
// This is fine because it does not require coverage instrumentation.
754
- if (!configuration.crashing_input_to_reproduce .has_value () &&
755
- fuzzer_impl_.ReplayInputsIfAvailable (configuration)) {
756
- result = 0 ;
764
+ FUZZTEST_INTERNAL_CHECK (
765
+ std::getenv (" FUZZTEST_REPLAY" ) ||
766
+ std::getenv (" FUZZTEST_MINIMIZE_REPRODUCER" ),
767
+ " Both env vars `FUZZTEST_REPLAY` and `FUZZTEST_MINIMIZE_REPRODUCER` "
768
+ " are not set when calling the legacy input replaying - this is a "
769
+ " FuzzTest bug!" );
770
+ fuzzer_impl_.fixture_driver_ ->RunFuzzTest ([&, this ]() {
771
+ FUZZTEST_INTERNAL_CHECK_PRECONDITION (
772
+ fuzzer_impl_.ReplayInputsIfAvailable (configuration),
773
+ " ReplayInputsIfAvailable failed to handle env vars `FUZZTEST_REPLAY` "
774
+ " or `FUZZTEST_MINIMIZE_REPRODUCER`. Please check if they are set "
775
+ " properly." );
757
776
return ;
758
- }
759
- // `ReplayInputsIfAvailable` overwrites the run mode - revert it back.
760
- runtime_.SetRunMode (mode);
761
- to_run_controller = true ;
762
- });
763
- if (!to_run_controller) return result == 0 ;
777
+ });
778
+ return true ;
779
+ }
764
780
// Run as the fuzzing engine.
781
+ int result = EXIT_FAILURE;
765
782
[&] {
766
783
runtime_.SetShouldTerminateOnNonFatalFailure (false );
767
784
std::unique_ptr<TempDir> workdir;
0 commit comments