From 66ff0756e421f0d702b1eeb8debee5c8903e1540 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 26 Feb 2016 22:42:23 +0000 Subject: [PATCH] [libFuzzer] add -print_final_stats=1 flag llvm-svn: 262084 --- llvm/lib/Fuzzer/FuzzerDriver.cpp | 2 ++ llvm/lib/Fuzzer/FuzzerFlags.def | 1 + llvm/lib/Fuzzer/FuzzerInternal.h | 8 ++++++++ llvm/lib/Fuzzer/FuzzerLoop.cpp | 17 ++++++++++++++--- llvm/lib/Fuzzer/FuzzerUtil.cpp | 8 ++++++++ llvm/lib/Fuzzer/test/fuzzer.test | 8 ++++++++ 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp index a3722e7..5741093 100644 --- a/llvm/lib/Fuzzer/FuzzerDriver.cpp +++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp @@ -301,6 +301,7 @@ static int FuzzerDriver(const std::vector &Args, Printf("Dictionary: %zd entries\n", Dictionary.size()); Options.SaveArtifacts = !Flags.test_single_input; Options.PrintNewCovPcs = Flags.print_new_cov_pcs; + Options.PrintFinalStats = Flags.print_final_stats; unsigned Seed = Flags.seed; // Initialize Seed. @@ -369,6 +370,7 @@ static int FuzzerDriver(const std::vector &Args, if (Flags.verbosity) Printf("Done %d runs in %zd second(s)\n", F.getTotalNumberOfRuns(), F.secondsSinceProcessStartUp()); + F.PrintFinalStats(); exit(0); // Don't let F destroy itself. } diff --git a/llvm/lib/Fuzzer/FuzzerFlags.def b/llvm/lib/Fuzzer/FuzzerFlags.def index a451436..aed3e4e 100644 --- a/llvm/lib/Fuzzer/FuzzerFlags.def +++ b/llvm/lib/Fuzzer/FuzzerFlags.def @@ -74,4 +74,5 @@ FUZZER_FLAG_INT(drill, 0, "Experimental: fuzz using a single unit as the seed " "corpus, then merge with the initial corpus") FUZZER_FLAG_INT(output_csv, 0, "Enable pulse output in CSV format.") FUZZER_FLAG_INT(print_new_cov_pcs, 0, "If 1, print out new covered pcs.") +FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.") diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 03905c2..62a77f8 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -85,6 +85,7 @@ std::string Hash(const Unit &U); void SetTimer(int Seconds); std::string Base64(const Unit &U); int ExecuteCommand(const std::string &Command); +size_t GetPeakRSSMb(); // Private copy of SHA1 implementation. static const int kSHA1NumBytes = 20; @@ -295,6 +296,7 @@ public: bool PrintNEW = true; // Print a status line when new units are found; bool OutputCSV = false; bool PrintNewCovPcs = false; + bool PrintFinalStats = false; }; Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options); void AddToCorpus(const Unit &U) { @@ -321,6 +323,10 @@ public: return duration_cast(system_clock::now() - ProcessStartTime) .count(); } + size_t execPerSec() { + size_t Seconds = secondsSinceProcessStartUp(); + return Seconds ? TotalNumberOfRuns / Seconds : 0; + } size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; } @@ -331,6 +337,7 @@ public: // Merge Corpora[1:] into Corpora[0]. void Merge(const std::vector &Corpora); MutationDispatcher &GetMD() { return MD; } + void PrintFinalStats(); private: void AlarmCallback(); @@ -372,6 +379,7 @@ private: size_t TotalNumberOfRuns = 0; size_t TotalNumberOfExecutedTraceBasedMutations = 0; + size_t NumberOfNewUnitsAdded = 0; std::vector Corpus; std::unordered_set UnitHashesAddedToCorpus; diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 82f1828..f2d24ce 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -92,6 +92,7 @@ void Fuzzer::DeathCallback() { } WriteUnitToFileWithPrefix( {CurrentUnitData, CurrentUnitData + CurrentUnitSize}, "crash-"); + PrintFinalStats(); } void Fuzzer::StaticAlarmCallback() { @@ -124,6 +125,7 @@ void Fuzzer::AlarmCallback() { if (__sanitizer_print_stack_trace) __sanitizer_print_stack_trace(); Printf("SUMMARY: libFuzzer: timeout\n"); + PrintFinalStats(); if (Options.AbortOnTimeout) abort(); exit(Options.TimeoutExitCode); @@ -131,9 +133,7 @@ void Fuzzer::AlarmCallback() { } void Fuzzer::PrintStats(const char *Where, const char *End) { - size_t Seconds = secondsSinceProcessStartUp(); - size_t ExecPerSec = (Seconds ? TotalNumberOfRuns / Seconds : 0); - + size_t ExecPerSec = execPerSec(); if (Options.OutputCSV) { static bool csvHeaderPrinted = false; if (!csvHeaderPrinted) { @@ -163,6 +163,16 @@ void Fuzzer::PrintStats(const char *Where, const char *End) { Printf("%s", End); } +void Fuzzer::PrintFinalStats() { + if (!Options.PrintFinalStats) return; + size_t ExecPerSec = execPerSec(); + Printf("stat::number_of_executed_units: %zd\n", TotalNumberOfRuns); + Printf("stat::average_exec_per_sec: %zd\n", ExecPerSec); + Printf("stat::new_units_added: %zd\n", NumberOfNewUnitsAdded); + Printf("stat::slowest_unit_time_sec: %zd\n", TimeOfLongestUnitInSeconds); + Printf("stat::peak_rss_mb: %zd\n", GetPeakRSSMb()); +} + void Fuzzer::RereadOutputCorpus() { if (Options.OutputCorpus.empty()) return; @@ -382,6 +392,7 @@ void Fuzzer::ReportNewCoverage(const Unit &U) { MD.RecordSuccessfulMutationSequence(); PrintStatusForNewUnit(U); WriteToOutputCorpus(U); + NumberOfNewUnitsAdded++; if (Options.ExitOnFirst) exit(0); } diff --git a/llvm/lib/Fuzzer/FuzzerUtil.cpp b/llvm/lib/Fuzzer/FuzzerUtil.cpp index 81462a4..1d51cf9 100644 --- a/llvm/lib/Fuzzer/FuzzerUtil.cpp +++ b/llvm/lib/Fuzzer/FuzzerUtil.cpp @@ -12,6 +12,7 @@ #include "FuzzerInternal.h" #include #include +#include #include #include #include @@ -217,4 +218,11 @@ std::string Base64(const Unit &U) { return Res; } +size_t GetPeakRSSMb() { + struct rusage usage; + if (getrusage(RUSAGE_SELF, &usage)) + return 0; + return usage.ru_maxrss >> 10; +} + } // namespace fuzzer diff --git a/llvm/lib/Fuzzer/test/fuzzer.test b/llvm/lib/Fuzzer/test/fuzzer.test index 3d9f5b4..b316337 100644 --- a/llvm/lib/Fuzzer/test/fuzzer.test +++ b/llvm/lib/Fuzzer/test/fuzzer.test @@ -69,3 +69,11 @@ RUN: rm %t/NthRunCrashTest.in RUN: not LLVMFuzzer-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator LLVMFuzzerCustomMutator: In LLVMFuzzerCustomMutator LLVMFuzzerCustomMutator: BINGO + +RUN: LLVMFuzzer-SimpleTest -seed=1 -runs=77 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS +FINAL_STATS: stat::number_of_executed_units: 77 +FINAL_STATS: stat::average_exec_per_sec: 0 +FINAL_STATS: stat::new_units_added: +FINAL_STATS: stat::slowest_unit_time_sec: 0 +FINAL_STATS: stat::peak_rss_mb: + -- 2.7.4