From 556425f9a9b6c0a2f4c7637b91893e186e62cf7a Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 19 May 2015 22:12:57 +0000 Subject: [PATCH] [lib/Fuzzer] change the meaning of -timeout flag: now timeout is applied to every unit of work separately git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237735 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Fuzzer/FuzzerDriver.cpp | 3 ++- lib/Fuzzer/FuzzerFlags.def | 5 ++++- lib/Fuzzer/FuzzerInternal.h | 1 + lib/Fuzzer/FuzzerLoop.cpp | 14 ++++++++++---- lib/Fuzzer/test/InfiniteTest.cpp | 4 ++++ lib/Fuzzer/test/fuzzer.test | 2 +- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index 6b8a4b220ef..dd0db86e02e 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -215,6 +215,7 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) { Fuzzer::FuzzingOptions Options; Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; + Options.UnitTimeoutSec = Flags.timeout; Options.DoCrossOver = Flags.cross_over; Options.MutateDepth = Flags.mutate_depth; Options.ExitOnFirst = Flags.exit_on_first; @@ -245,7 +246,7 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) { // Timer if (Flags.timeout > 0) - SetTimer(Flags.timeout); + SetTimer(Flags.timeout / 2 + 1); if (Flags.verbosity >= 2) { std::cerr << "Tokens: {"; diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 9d1b54524e9..c6fa388b728 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -27,7 +27,10 @@ FUZZER_FLAG_INT( " If 0, never do that. If -1, do it sometimes.") FUZZER_FLAG_INT(exit_on_first, 0, "If 1, exit after the first new interesting input is found.") -FUZZER_FLAG_INT(timeout, -1, "Timeout in seconds (if positive).") +FUZZER_FLAG_INT( + timeout, -1, + "Timeout in seconds (if positive). " + "If one unit runs more than this number of seconds the process will abort.") FUZZER_FLAG_INT(help, 0, "Print help.") FUZZER_FLAG_INT( save_minimized_corpus, 0, diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 80a2fc31c3a..b0c27b0da33 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -56,6 +56,7 @@ class Fuzzer { struct FuzzingOptions { int Verbosity = 1; int MaxLen = 0; + int UnitTimeoutSec = 300; bool DoCrossOver = true; int MutateDepth = 5; bool ExitOnFirst = false; diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index be1e9730e34..696811b4511 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -60,16 +60,20 @@ void Fuzzer::StaticAlarmCallback() { } void Fuzzer::AlarmCallback() { + assert(Options.UnitTimeoutSec > 0); size_t Seconds = duration_cast(system_clock::now() - UnitStartTime).count(); - std::cerr << "ALARM: working on the last Unit for " << Seconds << " seconds" - << std::endl; - if (Seconds >= 3) { + if (Seconds == 0) return; + if (Options.Verbosity >= 2) + std::cerr << "AlarmCallback " << Seconds << "\n"; + if (Seconds >= (size_t)Options.UnitTimeoutSec) { + std::cerr << "ALARM: working on the last Unit for " << Seconds << " seconds" + << std::endl; Print(CurrentUnit, "\n"); PrintUnitInASCIIOrTokens(CurrentUnit, "\n"); WriteToCrash(CurrentUnit, "timeout-"); + exit(1); } - exit(1); } void Fuzzer::PrintStats(const char *Where, size_t Cov, const char *End) { @@ -96,6 +100,8 @@ void Fuzzer::RereadOutputCorpus() { return; } if (!Options.Reload) return; + if (Options.Verbosity >= 2) + std::cerr << "Reload: read " << AdditionalCorpus.size() << " new units.\n"; for (auto &X : AdditionalCorpus) { if (X.size() > (size_t)Options.MaxLen) X.resize(Options.MaxLen); diff --git a/lib/Fuzzer/test/InfiniteTest.cpp b/lib/Fuzzer/test/InfiniteTest.cpp index 7c5c8c12713..b6d174ffdc9 100644 --- a/lib/Fuzzer/test/InfiniteTest.cpp +++ b/lib/Fuzzer/test/InfiniteTest.cpp @@ -6,6 +6,8 @@ static volatile int Sink; +static volatile int One = 1; + extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > 0 && Data[0] == 'H') { Sink = 1; @@ -13,6 +15,8 @@ extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { Sink = 2; if (Size > 2 && Data[2] == '!') { Sink = 2; + while (One) + ; } } } diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test index a4a2bcc1a41..aa2c7943fa7 100644 --- a/lib/Fuzzer/test/fuzzer.test +++ b/lib/Fuzzer/test/fuzzer.test @@ -4,7 +4,7 @@ RUN: ./LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s RUN: not ./LLVMFuzzer-InfiniteTest -timeout=2 2>&1 | FileCheck %s --check-prefix=InfiniteTest InfiniteTest: ALARM: working on the last Unit for -InfiniteTest-NOT: CRASHED; file written to timeout +InfiniteTest: CRASHED; file written to timeout RUN: not ./LLVMFuzzer-TimeoutTest -timeout=5 2>&1 | FileCheck %s --check-prefix=TimeoutTest TimeoutTest: ALARM: working on the last Unit for -- 2.34.1