Index: llvm/trunk/lib/Fuzzer/afl/afl_driver.cpp =================================================================== --- llvm/trunk/lib/Fuzzer/afl/afl_driver.cpp +++ llvm/trunk/lib/Fuzzer/afl/afl_driver.cpp @@ -60,6 +60,25 @@ static const size_t kMaxAflInputSize = 1 << 20; static uint8_t AflInputBuf[kMaxAflInputSize]; +// If the user asks us to duplicate stderr, then do it. +static void maybe_duplicate_stderr() { + char* stderr_duplicate_filename = + getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); + + if (!stderr_duplicate_filename) + return; + + FILE* stderr_duplicate_stream = + freopen(stderr_duplicate_filename, "a+", stderr); + + if (!stderr_duplicate_stream) { + fprintf(stderr, + "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME" + ); + abort(); + } +} + int main(int argc, char **argv) { fprintf(stderr, "Running in AFl-fuzz mode\nUsage:\n" "afl-fuzz [afl-flags] %s [N] " @@ -70,6 +89,8 @@ LLVMFuzzerInitialize(&argc, &argv); // Do any other expensive one-time initialization here. + maybe_duplicate_stderr(); + __afl_manual_init(); int N = 1000; Index: llvm/trunk/lib/Fuzzer/test/AFLDriverTest.cpp =================================================================== --- llvm/trunk/lib/Fuzzer/test/AFLDriverTest.cpp +++ llvm/trunk/lib/Fuzzer/test/AFLDriverTest.cpp @@ -0,0 +1,12 @@ +#include +#include + +extern "C" void __afl_manual_init() {} + +extern "C" int __afl_persistent_loop(unsigned int) { + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + return 0; +} Index: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt +++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt @@ -110,6 +110,19 @@ endforeach() ############################################################################### +# AFL Driver test +############################################################################### + +add_executable(AFLDriverTest + AFLDriverTest.cpp ../afl/afl_driver.cpp) + +set_target_properties(AFLDriverTest + PROPERTIES RUNTIME_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" + ) +set(TestBinaries ${TestBinaries} AFLDriverTest) + +############################################################################### # Unit tests ############################################################################### Index: llvm/trunk/lib/Fuzzer/test/afl-driver.test =================================================================== --- llvm/trunk/lib/Fuzzer/test/afl-driver.test +++ llvm/trunk/lib/Fuzzer/test/afl-driver.test @@ -0,0 +1,10 @@ +; Test that not specifying a file isn't broken. +RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME +RUN: AFLDriverTest + +; Test that specifying an invalid file causes a crash. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" not --crash AFLDriverTest + +; Test that a file is created when specified as the duplicate stderr. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t AFLDriverTest +RUN: stat %t