Index: lib/Fuzzer/afl/afl_driver.cpp =================================================================== --- lib/Fuzzer/afl/afl_driver.cpp +++ lib/Fuzzer/afl/afl_driver.cpp @@ -60,6 +60,21 @@ static const size_t kMaxAflInputSize = 1 << 20; static uint8_t AflInputBuf[kMaxAflInputSize]; +// If the user asks us to duplicate stderr, then do it. +void 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); + + assert(stderr_duplicate_stream && + "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); +} + int main(int argc, char **argv) { fprintf(stderr, "Running in AFl-fuzz mode\nUsage:\n" "afl-fuzz [afl-flags] %s [N] " @@ -70,6 +85,8 @@ LLVMFuzzerInitialize(&argc, &argv); // Do any other expensive one-time initialization here. + duplicate_stderr(); + __afl_manual_init(); int N = 1000; Index: lib/Fuzzer/test/AFLDriverTest.cpp =================================================================== --- /dev/null +++ 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: lib/Fuzzer/test/afl-driver.test =================================================================== --- /dev/null +++ lib/Fuzzer/test/afl-driver.test @@ -0,0 +1,13 @@ +RUN: clang++ %S/../afl/afl_driver.cpp %S/AFLDriverTest.cpp -o %T/test-afl-driver + +; Test that not specifying a file isn't broken. +RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME +RUN: %T/test-afl-driver + +; Test that specifying an invalid file causes a crash. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" ~/llvm/build/bin/not --crash %T/test-afl-driver + +; Test that a file is created when specified as the duplicate stderr. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t %T/test-afl-driver +RUN: stat %t +RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME