[llvm] r228170 - [fuzzer] make multi-process execution more verbose; fix mutation to actually respect mutation depth and to never produce empty units
Kostya Serebryany
kcc at google.com
Wed Feb 4 18:07:27 PST 2015
Ouch indeed. :(
On Wed, Feb 4, 2015 at 12:48 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>
> On Wed, Feb 4, 2015 at 12:44 PM, Sean Silva <chisophugis at gmail.com> wrote:
>
>> - bool MutateDepth = 10;
>> + int MutateDepth = 5;
>>
>> Ouch, I feel like we should maybe have a warning for this?
>>
>
> Agreed - we do have -Wliteral-conversion which catches some cases like
> this, but I don't think it catches cases where the destination is bool,
> unfortunately. I think I tried to improve this years ago & it was more work
> than I had time for, at the time.
>
> - David
>
>
>>
>> -- Sean Silva
>>
>> On Wed, Feb 4, 2015 at 11:10 AM, Kostya Serebryany <kcc at google.com>
>> wrote:
>>
>>> Author: kcc
>>> Date: Wed Feb 4 13:10:20 2015
>>> New Revision: 228170
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=228170&view=rev
>>> Log:
>>> [fuzzer] make multi-process execution more verbose; fix mutation to
>>> actually respect mutation depth and to never produce empty units
>>>
>>> Modified:
>>> llvm/trunk/lib/Fuzzer/FuzzerFlags.def
>>> llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
>>> llvm/trunk/lib/Fuzzer/FuzzerInternal.h
>>> llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
>>> llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
>>> llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Wed Feb 4 13:10:20 2015
>>> @@ -16,7 +16,7 @@ FUZZER_FLAG(int, iterations, -1,
>>> "Number of iterations of the fuzzer (-1 for infinite
>>> runs).")
>>> FUZZER_FLAG(int, max_len, 64, "Maximal length of the test input.")
>>> FUZZER_FLAG(int, cross_over, 1, "If 1, cross over inputs.")
>>> -FUZZER_FLAG(int, mutate_depth, 10,
>>> +FUZZER_FLAG(int, mutate_depth, 5,
>>> "Apply this number of consecutive mutations to each input.")
>>> FUZZER_FLAG(int, exit_on_first, 0,
>>> "If 1, exit after the first new interesting input is
>>> found.")
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerIO.cpp (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerIO.cpp Wed Feb 4 13:10:20 2015
>>> @@ -9,6 +9,8 @@
>>> // IO functions.
>>>
>>> //===----------------------------------------------------------------------===//
>>> #include "FuzzerInternal.h"
>>> +#include <iostream>
>>> +#include <iterator>
>>> #include <fstream>
>>> #include <dirent.h>
>>> namespace fuzzer {
>>> @@ -31,6 +33,12 @@ Unit FileToVector(const std::string &Pat
>>> std::istreambuf_iterator<char>());
>>> }
>>>
>>> +void CopyFileToErr(const std::string &Path) {
>>> + std::ifstream T(Path);
>>> + std::copy(std::istreambuf_iterator<char>(T),
>>> std::istreambuf_iterator<char>(),
>>> + std::ostream_iterator<char>(std::cerr, ""));
>>> +}
>>> +
>>> void WriteToFile(const Unit &U, const std::string &Path) {
>>> std::ofstream OF(Path);
>>> OF.write((const char*)U.data(), U.size());
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Wed Feb 4 13:10:20 2015
>>> @@ -23,6 +23,7 @@ using namespace std::chrono;
>>> Unit ReadFile(const char *Path);
>>> void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V);
>>> void WriteToFile(const Unit &U, const std::string &Path);
>>> +void CopyFileToErr(const std::string &Path);
>>> // Returns "Dir/FileName" or equivalent for the current OS.
>>> std::string DirPlusFile(const std::string &DirPath,
>>> const std::string &FileName);
>>> @@ -42,7 +43,7 @@ class Fuzzer {
>>> int Verbosity = 1;
>>> int MaxLen = 0;
>>> bool DoCrossOver = true;
>>> - bool MutateDepth = 10;
>>> + int MutateDepth = 5;
>>> bool ExitOnFirst = false;
>>> bool UseFullCoverageSet = false;
>>> std::string OutputCorpus;
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Feb 4 13:10:20 2015
>>> @@ -146,9 +146,8 @@ void Fuzzer::SaveCorpus() {
>>>
>>> size_t Fuzzer::MutateAndTestOne(Unit *U) {
>>> size_t NewUnits = 0;
>>> - for (size_t i = 0; i < Options.MutateDepth; i++) {
>>> + for (int i = 0; i < Options.MutateDepth; i++) {
>>> Mutate(U, Options.MaxLen);
>>> - if (U->empty()) continue;
>>> size_t NewCoverage = RunOne(*U);
>>> if (NewCoverage) {
>>> Corpus.push_back(*U);
>>> @@ -158,6 +157,7 @@ size_t Fuzzer::MutateAndTestOne(Unit *U)
>>> << "\tNEW: " << NewCoverage
>>> << " L: " << U->size()
>>> << " S: " << Corpus.size()
>>> + << " I: " << i
>>> << "\t";
>>> if (U->size() < 30) {
>>> PrintASCII(*U);
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerMain.cpp (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerMain.cpp Wed Feb 4 13:10:20 2015
>>> @@ -17,6 +17,7 @@
>>> #include <iostream>
>>> #include <thread>
>>> #include <atomic>
>>> +#include <mutex>
>>>
>>> // ASAN options:
>>> // * don't dump the coverage to disk.
>>> @@ -105,20 +106,30 @@ static void ParseFlags(int argc, char **
>>> }
>>>
>>> static void WorkerThread(const std::string &Cmd, std::atomic<int>
>>> *Counter,
>>> - int NumJobs) {
>>> + int NumJobs, std::atomic<bool> *HasErrors) {
>>> + static std::mutex CerrMutex;
>>> while (true) {
>>> int C = (*Counter)++;
>>> - if (C >= NumJobs) return;
>>> - std::string ToRun = Cmd + " > fuzz-" + std::to_string(C) + ".log
>>> 2>&1\n";
>>> + if (C >= NumJobs) break;
>>> + std::string Log = "fuzz-" + std::to_string(C) + ".log";
>>> + std::string ToRun = Cmd + " > " + Log + " 2>&1\n";
>>> if (Flags.verbosity)
>>> std::cerr << ToRun;
>>> - system(ToRun.c_str());
>>> + int ExitCode = system(ToRun.c_str());
>>> + if (ExitCode != 0)
>>> + *HasErrors = true;
>>> + std::lock_guard<std::mutex> Lock(CerrMutex);
>>> + std::cerr << "================== Job " << C
>>> + << " exited with exit code " << ExitCode
>>> + << " =================\n";
>>> + fuzzer::CopyFileToErr(Log);
>>> }
>>> }
>>>
>>> static int RunInMultipleProcesses(int argc, char **argv, int NumWorkers,
>>> int NumJobs) {
>>> std::atomic<int> Counter(0);
>>> + std::atomic<bool> HasErrors(false);
>>> std::string Cmd;
>>> for (int i = 0; i < argc; i++) {
>>> if (FlagValue(argv[i], "jobs") || FlagValue(argv[i], "workers"))
>>> continue;
>>> @@ -127,10 +138,10 @@ static int RunInMultipleProcesses(int ar
>>> }
>>> std::vector<std::thread> V;
>>> for (int i = 0; i < NumWorkers; i++)
>>> - V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs));
>>> + V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs,
>>> &HasErrors));
>>> for (auto &T : V)
>>> T.join();
>>> - return 0;
>>> + return HasErrors ? 1 : 0;
>>> }
>>>
>>> int main(int argc, char **argv) {
>>>
>>> Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
>>> +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Wed Feb 4 13:10:20 2015
>>> @@ -31,18 +31,25 @@ static char RandCh() {
>>> return Special[rand() % (sizeof(Special) - 1)];
>>> }
>>>
>>> +// Mutate U in place.
>>> void Mutate(Unit *U, size_t MaxLen) {
>>> assert(MaxLen > 0);
>>> assert(U->size() <= MaxLen);
>>> + if (U->empty()) {
>>> + for (size_t i = 0; i < MaxLen; i++)
>>> + U->push_back(RandCh());
>>> + return;
>>> + }
>>> + assert(!U->empty());
>>> switch (rand() % 3) {
>>> case 0:
>>> - if (U->size())
>>> + if (U->size() > 1) {
>>> U->erase(U->begin() + rand() % U->size());
>>> - break;
>>> + break;
>>> + }
>>> + // Fallthrough
>>> case 1:
>>> - if (U->empty()) {
>>> - U->push_back(RandCh());
>>> - } else if (U->size() < MaxLen) {
>>> + if (U->size() < MaxLen) {
>>> U->insert(U->begin() + rand() % U->size(), RandCh());
>>> } else { // At MaxLen.
>>> uint8_t Ch = RandCh();
>>> @@ -51,12 +58,13 @@ void Mutate(Unit *U, size_t MaxLen) {
>>> }
>>> break;
>>> default:
>>> - if (!U->empty()) {
>>> - size_t idx = rand() % U->size();
>>> - (*U)[idx] = FlipRandomBit((*U)[idx]);
>>> + {
>>> + size_t Idx = rand() % U->size();
>>> + (*U)[Idx] = FlipRandomBit((*U)[Idx]);
>>> }
>>> break;
>>> }
>>> + assert(!U->empty());
>>> }
>>>
>>> } // namespace fuzzer
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150204/d737f6a2/attachment.html>
More information about the llvm-commits
mailing list