Index: docs/LibFuzzer.rst =================================================================== --- docs/LibFuzzer.rst +++ docs/LibFuzzer.rst @@ -68,6 +68,7 @@ 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``. Index: lib/Fuzzer/FuzzerDriver.cpp =================================================================== --- lib/Fuzzer/FuzzerDriver.cpp +++ lib/Fuzzer/FuzzerDriver.cpp @@ -202,6 +202,12 @@ 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 @@ 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) Index: lib/Fuzzer/FuzzerFlags.def =================================================================== --- lib/Fuzzer/FuzzerFlags.def +++ lib/Fuzzer/FuzzerFlags.def @@ -66,3 +66,4 @@ "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 Index: lib/Fuzzer/FuzzerInternal.h =================================================================== --- lib/Fuzzer/FuzzerInternal.h +++ lib/Fuzzer/FuzzerInternal.h @@ -115,10 +115,10 @@ 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); Index: lib/Fuzzer/test/fuzzer.test =================================================================== --- lib/Fuzzer/test/fuzzer.test +++ 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 Index: lib/Fuzzer/test/hi.txt =================================================================== --- /dev/null +++ lib/Fuzzer/test/hi.txt @@ -0,0 +1 @@ +Hi! \ No newline at end of file