Code now exists to track number of mutations that are used in fuzzing in total
and ones that produce new coverage. The stats are currently being dumped to the
command line.
Patch by Kodé Williams (@kodewilliams).
Differential D48054
[libFuzzer] Mutation tracking and logging implemented. kodewilliams on Jun 11 2018, 2:48 PM. Authored by
Details
Code now exists to track number of mutations that are used in fuzzing in total Patch by Kodé Williams (@kodewilliams).
Diff Detail
Event TimelineThere are a very large number of changes, so older changes are hidden. Show Older Changes
Comment Actions @Dor1s I still think using a map that contains string -> count makes most sense.
Comment Actions
I meant unordered_map Comment Actions Kode, you also need to write a test for the functionality your're adding. Please check out the section regarding the tests in LLVM Dev Starting Kit. Then, take a look at the existing tests: https://github.com/llvm-mirror/compiler-rt/tree/master/test/fuzzer, especially at "fuzzer-finalstats.test". While thinking about the test, I've realized the following. Since we eventually plan to remove the detailed statistics output (with mutation names), we will have to update the tests after that. The fact that we have that detailed output right now would also slightly complicate writing a test for you. So, my proposal would be to remove the detailed output at all, just print those useful / total float numbers in a single line, as we discussed today. We still be using MutationType enum type for tracking mutation stats, but we can get rid of kMutationNames and the code that uses it. Struct Mutator would have both name and identifier. That would simplify the code and also automatically address some of Jonathan's comments.
Comment Actions Did you forget to do git add for the test file you've written?
Comment Actions Left some minor comments, looks good otherwise! Once Jonathan is also happy with that, we should add Matt (@morehouse) as the next review step.
Comment Actions Since Matt got automatically added to the subscribers, here is some context. Kode is an intern on our team who is looking into leveraging mutation usefulness statistics somehow to improve fuzzing efficiency. This step only adds stats computation under an experimental flag. The next step would be to enable those stats on ClusterFuzz and collect usefulness distribution from various fuzz targets running in various circumstances. While stats will be collected, Kode will be trying different approaches for mutation selection algorithm (instead of existing Rand()) and, as a result, expected to add that new algorithm under this or another experimental flag.
Comment Actions It looks like the line numbers on my last comments were messed up, trying again.
Comment Actions Removed FuzzerMutationStats.* files and simplified implementation inside FuzzerMutate.
Comment Actions the current patch is hard to review as it contains tons of formatting (or otherwise unrelated) fixed.
Comment Actions Reverted due to bot breakage in r336616. FAIL: libFuzzer :: fuzzer-custommutator.test (6330 of 6439) ******************** TEST 'libFuzzer :: fuzzer-custommutator.test' FAILED ******************** Script: -- : 'RUN: at line 1'; /b/sanitizer-x86_64-linux/build/llvm_build64/bin/clang --driver-mode=g++ -std=c++11 -lstdc++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer -m64 /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/fuzzer/CustomMutatorTest.cpp -o /b/sanitizer-x86_64-linux/build/compiler_rt_build/test/fuzzer/Output/fuzzer-custommutator.test.tmp-CustomMutatorTest : 'RUN: at line 2'; not /b/sanitizer-x86_64-linux/build/compiler_rt_build/test/fuzzer/Output/fuzzer-custommutator.test.tmp-CustomMutatorTest 2>&1 | FileCheck /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/fuzzer/fuzzer-custommutator.test --check-prefix=LLVMFuzzerCustomMutator -- Exit Code: 1 Command Output (stderr): -- /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/fuzzer/fuzzer-custommutator.test:4:26: error: expected string not found in input LLVMFuzzerCustomMutator: BINGO ^ <stdin>:8:1: note: scanning from here ================================================================= ^ <stdin>:9:9: note: possible intended match here ==57316==ERROR: AddressSanitizer: attempting double-free on 0x602000000050 in thread T0: ^ See http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fuzzer/builds/16996. Comment Actions @morehouse I have been looking over the code and I cannot seem to find a reason why that single test is failing. PTAL. Comment Actions I have seen the same failure when the commit was landed and I debugged it a little bit. The problem was that CustomMutatorTest.cpp's LLVMFuzzerCustomMutator implementation calls LLVMFuzzerMutate, which uses the default set of mutators. This causes a discrepancy: MutateImpl will log into CurrentMutatorIdxSequence that a mutator with an index between 0..12 (from the default set) was used, but when printing the sequence (in PrintMutationSequence), we only expect to find indexes from MutationDispatcher::Mutators. When using a custom mutator (like in this test), MutationDispatcher::Mutators only has one element. So PrintMutationSequence overflows the vector when it tries to use an index from 0..12. Add a if (M >= Mutators.size()) abort(); line into PrintMutationSequence and run the test to reproduce this. Comment Actions I suspect this has something to do with LLVMFuzzerMutate being called from CustomMutatorTest.cpp, which uses DefaultMutators instead of Mutators. So your CurrentMutatorIdxSequence vector gets indexes from both DefaultMutators and Mutators.
Comment Actions I'm seeing a build failure on one of the bots http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/13625/steps/build%20with%20ninja/logs/stdio : [3726/4950] Building CXX object projects/compiler-rt/lib/fuzzer/CMakeFiles/RTfuzzer.x86_64.dir/FuzzerMutate.cpp.o FAILED: projects/compiler-rt/lib/fuzzer/CMakeFiles/RTfuzzer.x86_64.dir/FuzzerMutate.cpp.o /b/sanitizer-x86_64-linux/build/clang_build/bin/clang++ -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iprojects/compiler-rt/lib/fuzzer -I/b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer -I/usr/include/libxml2 -Iinclude -I/b/sanitizer-x86_64-linux/build/llvm/include -gmlt -fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Werror -std=c++11 -Wno-unused-parameter -O3 -UNDEBUG -gmlt -fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Werror -std=c++11 -Wno-unused-parameter -m64 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -O3 -gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -Wno-non-virtual-dtor -nostdinc++ -D_LIBCPP_ABI_VERSION=Fuzzer -fno-omit-frame-pointer -isystem /b/sanitizer-x86_64-linux/build/llvm_build_ninja/projects/compiler-rt/lib/fuzzer/libcxx_fuzzer_x86_64/include/c++/v1 -MD -MT projects/compiler-rt/lib/fuzzer/CMakeFiles/RTfuzzer.x86_64.dir/FuzzerMutate.cpp.o -MF projects/compiler-rt/lib/fuzzer/CMakeFiles/RTfuzzer.x86_64.dir/FuzzerMutate.cpp.o.d -o projects/compiler-rt/lib/fuzzer/CMakeFiles/RTfuzzer.x86_64.dir/FuzzerMutate.cpp.o -c /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:33:64: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:34:64: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_InsertByte, "InsertByte"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:36:33: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] "InsertRepeatedBytes"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:37:64: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:38:62: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:39:68: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:40:76: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:41:75: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:42:60: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_CopyPart, "CopyPart"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:43:62: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_CrossOver, "CrossOver"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:45:24: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] "ManualDict"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:47:26: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] "PersAutoDict"}, ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:51:60: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP"}); ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:54:69: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"}); ^ /b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMutate.cpp:60:72: error: missing field 'UsefulCount' initializer [-Werror,-Wmissing-field-initializers] {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"}); ^ 15 errors generated. Comment Actions Reverted in https://reviews.llvm.org/rCRT337206. Kode, please add -DLLVM_ENABLE_WERROR=ON flag to your cmake command to reproduce the failure locally. Comment Actions Actually, I think you might've already used that flag (it is used in LLVM Dev Starting Kit). In that case, you would need to add -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, I think. Comment Actions I think it's fine to land. Kostya approved the previous version, and he probably won't mind the extra 0's in the initialization lists. It isn't as clean looking, but it silences the warning, and it's probably good practice to specify all fields in the list anyway. |
Can we include this only in the files that need it?