Skip to content

Commit e4ce81e

Browse files
xinhaoyuancopybara-github
authored andcommitted
Use the stop time to cap command deadlines, and skip reporting crashes after it.
This allows the stop time to be enforced more precisely instead of having to wait for the entire batch, without reporting the potential crashes due to interrupting the command. After this we don't need to set batch timeout to the test time limit - it was a quick workaround for the same requirement. PiperOrigin-RevId: 791875139
1 parent b742bb0 commit e4ce81e

File tree

7 files changed

+24
-39
lines changed

7 files changed

+24
-39
lines changed

centipede/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ cc_library(
666666
":runner_request",
667667
":runner_result",
668668
":shared_memory_blob_sequence",
669+
":stop",
669670
":util",
670671
":workdir",
671672
"@abseil-cpp//absl/base:nullability",

centipede/centipede.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ bool Centipede::RunBatch(
425425
success;
426426
}
427427
if (EarlyStopRequested()) return false;
428-
if (!success && env_.exit_on_crash) {
428+
if (!success && env_.exit_on_crash && !ShouldStop()) {
429429
FUZZTEST_LOG(INFO) << "--exit_on_crash is enabled; exiting soon";
430430
RequestEarlyStop(EXIT_FAILURE);
431431
return false;
@@ -881,6 +881,13 @@ void Centipede::ReportCrash(std::string_view binary,
881881
const BatchResult &batch_result) {
882882
FUZZTEST_CHECK_EQ(input_vec.size(), batch_result.results().size());
883883

884+
if (ShouldStop()) {
885+
FUZZTEST_LOG_FIRST_N(WARNING, 1)
886+
<< "Stop condition met - not reporting further crashes possibly "
887+
"related to the stop condition.";
888+
return;
889+
}
890+
884891
const size_t suspect_input_idx = std::clamp<size_t>(
885892
batch_result.num_outputs_read(), 0, input_vec.size() - 1);
886893
auto log_execution_failure = [&](std::string_view log_prefix) {

centipede/centipede_callbacks.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "./centipede/mutation_input.h"
5151
#include "./centipede/runner_request.h"
5252
#include "./centipede/runner_result.h"
53+
#include "./centipede/stop.h"
5354
#include "./centipede/util.h"
5455
#include "./centipede/workdir.h"
5556
#include "./common/blob_file.h"
@@ -479,7 +480,8 @@ int CentipedeCallbacks::RunBatchForBinary(std::string_view binary) {
479480
env_.timeout_per_batch == 0
480481
? absl::InfiniteDuration()
481482
: absl::Seconds(env_.timeout_per_batch) + absl::Seconds(5);
482-
const auto deadline = absl::Now() + amortized_timeout;
483+
const auto deadline =
484+
std::min(absl::Now() + amortized_timeout, GetStopTime());
483485
int exit_code = EXIT_SUCCESS;
484486
const bool should_clean_up = [&] {
485487
if (!cmd.is_executing() && !cmd.ExecuteAsync()) {
@@ -497,11 +499,12 @@ int CentipedeCallbacks::RunBatchForBinary(std::string_view binary) {
497499
if (should_clean_up) {
498500
exit_code = [&] {
499501
if (!cmd.is_executing()) return EXIT_FAILURE;
500-
FUZZTEST_LOG(ERROR) << "Cleaning up the batch execution.";
502+
FUZZTEST_LOG(ERROR) << "Cleaning up the batch execution with timeout "
503+
<< kCommandCleanupTimeout;
501504
cmd.RequestStop();
502505
const auto ret = cmd.Wait(absl::Now() + kCommandCleanupTimeout);
503506
if (ret.has_value()) return *ret;
504-
FUZZTEST_LOG(ERROR) << "Batch execution cleanup failed to end in 60s.";
507+
FUZZTEST_LOG(ERROR) << "Failed to wait for the batch execution cleanup.";
505508
return EXIT_FAILURE;
506509
}();
507510
command_contexts_.erase(

centipede/environment.cc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,6 @@ void Environment::UpdateWithTargetConfig(
285285
timeout_per_input = time_limit_per_input_sec;
286286
UpdateTimeoutPerBatchIfEqualTo(autocomputed_timeout_per_batch);
287287

288-
// Adjust `timeout_per_batch` to never exceed the test time limit.
289-
if (const auto test_time_limit = config.GetTimeLimitPerTest();
290-
test_time_limit < absl::InfiniteDuration()) {
291-
const size_t test_time_limit_seconds =
292-
convert_to_seconds(test_time_limit, "Test time limit");
293-
timeout_per_batch =
294-
timeout_per_batch == 0
295-
? test_time_limit_seconds
296-
: std::min(timeout_per_batch, test_time_limit_seconds);
297-
}
298-
299288
// Convert bytes to MB by rounding up.
300289
constexpr auto bytes_to_mb = [](size_t bytes) {
301290
return bytes == 0 ? 0 : (bytes - 1) / 1024 / 1024 + 1;

centipede/environment_test.cc

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -147,30 +147,6 @@ TEST(Environment,
147147
EXPECT_EQ(env.timeout_per_batch, 0);
148148
}
149149

150-
TEST(Environment, UpdatesTimeoutPerBatchFromTargetConfigTimeLimit) {
151-
Environment env;
152-
fuzztest::internal::Configuration config;
153-
config.time_limit = absl::Seconds(123);
154-
config.time_budget_type = fuzztest::internal::TimeBudgetType::kPerTest;
155-
FUZZTEST_CHECK(config.GetTimeLimitPerTest() == absl::Seconds(123));
156-
env.UpdateWithTargetConfig(config);
157-
EXPECT_EQ(env.timeout_per_batch, 123)
158-
<< "`timeout_per_batch` should be set to the test time limit when it was "
159-
"previously unset";
160-
161-
env.timeout_per_batch = 456;
162-
env.UpdateWithTargetConfig(config);
163-
EXPECT_EQ(env.timeout_per_batch, 123)
164-
<< "`timeout_per_batch` should be set to test time limit when it is "
165-
"shorter than the previous value";
166-
167-
env.timeout_per_batch = 56;
168-
env.UpdateWithTargetConfig(config);
169-
EXPECT_EQ(env.timeout_per_batch, 56)
170-
<< "`timeout_per_batch` should not be updated with the test time limit "
171-
"when it is longer than the previous value";
172-
}
173-
174150
TEST(Environment, UpdatesRssLimitMbFromTargetConfigRssLimit) {
175151
Environment env;
176152
env.rss_limit_mb = Environment::Default().rss_limit_mb;

centipede/stop.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ void RequestEarlyStop(int exit_code) {
4646
early_stop.store({exit_code, true}, std::memory_order_release);
4747
}
4848

49+
absl::Time GetStopTime() { return stop_time; }
50+
4951
bool ShouldStop() { return EarlyStopRequested() || stop_time < absl::Now(); }
5052

5153
int ExitCode() { return early_stop.load(std::memory_order_acquire).exit_code; }

centipede/stop.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ bool EarlyStopRequested();
4646
// ENSURES: Thread-safe.
4747
bool ShouldStop();
4848

49+
// Returns the stop time set from the recent
50+
// `ClearEarlyStopRequestAndSetStopTime()`, or `absl::InfiniteFuture()` it was
51+
// not set.
52+
//
53+
// ENSURES: Thread-safe.
54+
absl::Time GetStopTime();
55+
4956
// Returns the value most recently passed to `RequestEarlyStop()` or 0 if
5057
// `RequestEarlyStop()` was not called since the most recent call to
5158
// `ClearEarlyStopRequestAndSetStopTime()` (if any).

0 commit comments

Comments
 (0)