#Centipede Clean up cmp traces on coverage cleanup. This particularly improves the FuzzTest/Centipede single-process integration, where the fuzzing engine would generate noise to the cmps traces and make the mutation less effective if the noise is not cleaned up. PiperOrigin-RevId: 596940201
diff --git a/centipede/BUILD b/centipede/BUILD index 12ebb71..b89a6a8 100644 --- a/centipede/BUILD +++ b/centipede/BUILD
@@ -1628,6 +1628,7 @@ srcs = ["centipede_test.cc"], data = [ "@com_google_fuzztest//centipede/testing:abort_fuzz_target", + "@com_google_fuzztest//centipede/testing:expensive_startup_fuzz_target", "@com_google_fuzztest//centipede/testing:seeded_fuzz_target", "@com_google_fuzztest//centipede/testing:test_fuzz_target", "@com_google_fuzztest//centipede/testing:test_input_filter",
diff --git a/centipede/centipede_test.cc b/centipede/centipede_test.cc index d77d42f..21065b6 100644 --- a/centipede/centipede_test.cc +++ b/centipede/centipede_test.cc
@@ -864,4 +864,22 @@ {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}})); } +TEST(Centipede, CleansUpMetadataAfterStartup) { + Environment env; + env.binary = GetDataDependencyFilepath( + "centipede/testing/expensive_startup_fuzz_target"); + CentipedeDefaultCallbacks callbacks(env); + BatchResult batch_result; + const std::vector<ByteArray> inputs = {{0}}; + ASSERT_TRUE(callbacks.Execute(env.binary, inputs, batch_result)); + ASSERT_EQ(batch_result.results().size(), 1); + bool found_startup_cmp_entry = false; + batch_result.results()[0].metadata().ForEachCmpEntry( + [&](ByteSpan a, ByteSpan b) { + if (a == ByteArray{'F', 'u', 'z', 'z'}) found_startup_cmp_entry = true; + if (b == ByteArray{'F', 'u', 'z', 'z'}) found_startup_cmp_entry = true; + }); + EXPECT_FALSE(found_startup_cmp_entry); +} + } // namespace centipede
diff --git a/centipede/runner.cc b/centipede/runner.cc index 3427bc8..4e1ab3f 100644 --- a/centipede/runner.cc +++ b/centipede/runner.cc
@@ -378,8 +378,15 @@ tls.lowest_sp = tls.top_frame_sp; }); } - // TODO(kcc): do we need to clear tls.cmp_trace2 and others here? if (!full_clear) return; + state.ForEachTls([](ThreadLocalRunnerState &tls) { + if (state.run_time_flags.use_auto_dictionary) { + tls.cmp_trace2.Clear(); + tls.cmp_trace4.Clear(); + tls.cmp_trace8.Clear(); + tls.cmp_traceN.Clear(); + } + }); state.pc_counter_set.ForEachNonZeroByte([](size_t idx, uint8_t value) {}); if (state.run_time_flags.use_dataflow_features) state.data_flow_feature_set.ForEachNonZeroBit([](size_t idx) {});
diff --git a/centipede/testing/expensive_startup_fuzz_target.cc b/centipede/testing/expensive_startup_fuzz_target.cc index 354f5e1..61d5b8e 100644 --- a/centipede/testing/expensive_startup_fuzz_target.cc +++ b/centipede/testing/expensive_startup_fuzz_target.cc
@@ -15,16 +15,20 @@ #include <cstddef> #include <cstdint> #include <cstdio> +#include <cstring> static int sink; // Instrumented function that runs at startup. We want it's coverage ignored. -__attribute__((constructor, noinline)) void Startup() { +__attribute__((constructor, noinline, optnone)) void Startup() { fprintf(stderr, "Startup\n"); // Function entry: generate a coverage feature. sink++; // generate data flow feature if (sink == (sink == 42)) // generate some cmp features Startup(); + char str[] = {'F', 'u', 'z', 'z'}; + if (memcmp(str, "Null", 4) == 0) // generate some cmp traces + Startup(); } // A fuzz target used for testing Centipede.