From b941371206bddc759a7ce37070c956d56e5b71c7 Mon Sep 17 00:00:00 2001 From: Ivan Krasin Date: Thu, 1 Oct 2015 23:23:06 +0000 Subject: [PATCH] [LibFuzzer] test_single_input option to run a single test case. -test_single_input flag specifies a file name with test data. Review URL: http://reviews.llvm.org/D13359 Patch by Mike Aizatsky! llvm-svn: 249096 --- docs/LibFuzzer.rst | 1 + lib/Fuzzer/FuzzerDriver.cpp | 9 +++++++++ lib/Fuzzer/FuzzerFlags.def | 1 + lib/Fuzzer/FuzzerInternal.h | 2 +- lib/Fuzzer/test/fuzzer.test | 1 + lib/Fuzzer/test/hi.txt | 1 + 6 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 lib/Fuzzer/test/hi.txt diff --git a/docs/LibFuzzer.rst b/docs/LibFuzzer.rst index a5114bbf083..a9948d893e1 100644 --- a/docs/LibFuzzer.rst +++ b/docs/LibFuzzer.rst @@ -68,6 +68,7 @@ The most important flags are:: sync_timeout 600 Minimum timeout between syncs. use_traces 0 Experimental: use instruction traces only_ascii 0 If 1, generate only ASCII (isprint+isspace) inputs. + test_single_input "" Use specified file content as test input. Test will be run only once. Useful for debugging a particular case. For the full list of flags run the fuzzer binary with ``-help=1``. diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index e79c21e8bdb..9c4406e219c 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -202,6 +202,12 @@ int ApplyTokens(const Fuzzer &F, const char *InputFilePath) { return 0; } +int RunOneTest(Fuzzer *F, const char *InputFilePath) { + Unit U = FileToVector(InputFilePath); + F->ExecuteCallback(U); + return 0; +} + int FuzzerDriver(int argc, char **argv, UserCallback Callback) { FuzzerRandomLibc Rand(0); SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); @@ -275,6 +281,9 @@ int FuzzerDriver(const std::vector &Args, if (Flags.apply_tokens) return ApplyTokens(F, Flags.apply_tokens); + if (Flags.test_single_input) + return RunOneTest(&F, Flags.test_single_input); + unsigned Seed = Flags.seed; // Initialize Seed. if (Seed == 0) diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 824c9f1b912..3b2a0f5544c 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -66,3 +66,4 @@ FUZZER_FLAG_INT(tbm_depth, 5, "Apply at most this number of consecutive" "trace-based-mutations (tbm).") FUZZER_FLAG_INT(tbm_width, 5, "Apply at most this number of independent" "trace-based-mutations (tbm)") +FUZZER_FLAG_STRING(test_single_input, "Use specified file as test input.") \ No newline at end of file diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 334800e8275..862732eedf7 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -115,10 +115,10 @@ class Fuzzer { static void StaticAlarmCallback(); Unit SubstituteTokens(const Unit &U) const; + void ExecuteCallback(const Unit &U); private: void AlarmCallback(); - void ExecuteCallback(const Unit &U); void MutateAndTestOne(Unit *U); void ReportNewCoverage(size_t NewCoverage, const Unit &U); size_t RunOne(const Unit &U); diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test index 70dbce80554..29bd8071000 100644 --- a/lib/Fuzzer/test/fuzzer.test +++ b/lib/Fuzzer/test/fuzzer.test @@ -1,6 +1,7 @@ CHECK: BINGO RUN: LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s +RUN: LLVMFuzzer-SimpleTest -test_single_input=%S/hi.txt 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 diff --git a/lib/Fuzzer/test/hi.txt b/lib/Fuzzer/test/hi.txt new file mode 100644 index 00000000000..2f9031f0ec7 --- /dev/null +++ b/lib/Fuzzer/test/hi.txt @@ -0,0 +1 @@ +Hi! \ No newline at end of file