[compiler-rt] r311797 - [libFuzzer] add -print_funcs=1 (on bey default): print newly discovered functions during fuzzing

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 25 13:09:25 PDT 2017


Author: kcc
Date: Fri Aug 25 13:09:25 2017
New Revision: 311797

URL: http://llvm.org/viewvc/llvm-project?rev=311797&view=rev
Log:
[libFuzzer] add -print_funcs=1 (on bey default): print newly discovered functions during fuzzing

Added:
    compiler-rt/trunk/test/fuzzer/PrintFuncTest.cpp
    compiler-rt/trunk/test/fuzzer/print-func.test
Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
    compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
    compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Fri Aug 25 13:09:25 2017
@@ -603,6 +603,7 @@ int FuzzerDriver(int *argc, char ***argv
   Options.SaveArtifacts =
       !DoPlainRun || Flags.minimize_crash_internal_step;
   Options.PrintNewCovPcs = Flags.print_pcs;
+  Options.PrintNewCovFuncs = Flags.print_funcs;
   Options.PrintFinalStats = Flags.print_final_stats;
   Options.PrintCorpusStats = Flags.print_corpus_stats;
   Options.PrintCoverage = Flags.print_coverage;

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Fri Aug 25 13:09:25 2017
@@ -91,6 +91,7 @@ FUZZER_FLAG_STRING(exact_artifact_path,
                    "and will not use checksum in the file name. Do not "
                    "use the same path for several parallel processes.")
 FUZZER_FLAG_INT(print_pcs, 0, "If 1, print out newly covered PCs.")
+FUZZER_FLAG_INT(print_funcs, 1, "If 1, print out newly covered functions.")
 FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.")
 FUZZER_FLAG_INT(print_corpus_stats, 0,
   "If 1, print statistics on corpus elements at exit.")

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Fri Aug 25 13:09:25 2017
@@ -626,6 +626,7 @@ void Fuzzer::MutateAndTestOne() {
 
 void Fuzzer::Loop() {
   TPC.SetPrintNewPCs(Options.PrintNewCovPcs);
+  TPC.SetPrintNewFuncs(Options.PrintNewCovFuncs);
   system_clock::time_point LastCorpusReload = system_clock::now();
   if (Options.DoCrossOver)
     MD.SetCorpus(&Corpus);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h Fri Aug 25 13:09:25 2017
@@ -47,6 +47,7 @@ struct FuzzingOptions {
   bool SaveArtifacts = true;
   bool PrintNEW = true; // Print a status line when new units are found;
   bool PrintNewCovPcs = false;
+  bool PrintNewCovFuncs = false;
   bool PrintFinalStats = false;
   bool PrintCorpusStats = false;
   bool PrintCoverage = false;

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp Fri Aug 25 13:09:25 2017
@@ -143,11 +143,18 @@ void TracePC::HandleCallerCallee(uintptr
 }
 
 void TracePC::UpdateObservedPCs() {
-  auto Observe = [&](uintptr_t PC) {
-    bool Inserted = ObservedPCs.insert(PC).second;
-    if (Inserted && DoPrintNewPCs)
+  auto ObservePC = [&](uintptr_t PC) {
+    if (ObservedPCs.insert(PC).second && DoPrintNewPCs)
       PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);
   };
+
+  auto Observe = [&](const PCTableEntry &TE) {
+    if (TE.PCFlags & 1)
+      if (ObservedFuncs.insert(TE.PC).second && DoPrintNewFuncs)
+        PrintPC("\tNEW_FUNC: %p %F %L\n", "\tNEW_PC: %p\n", TE.PC + 1);
+    ObservePC(TE.PC);
+  };
+
   if (NumPCsInPCTables) {
     if (NumInline8bitCounters == NumPCsInPCTables) {
       for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
@@ -157,7 +164,7 @@ void TracePC::UpdateObservedPCs() {
                (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
         for (size_t j = 0; j < Size; j++)
           if (Beg[j])
-            Observe(ModulePCTable[i].Start[j].PC);
+            Observe(ModulePCTable[i].Start[j]);
       }
     } else if (NumGuards == NumPCsInPCTables) {
       size_t GuardIdx = 1;
@@ -168,7 +175,7 @@ void TracePC::UpdateObservedPCs() {
                (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
         for (size_t j = 0; j < Size; j++, GuardIdx++)
           if (Counters()[GuardIdx])
-            Observe(ModulePCTable[i].Start[j].PC);
+            Observe(ModulePCTable[i].Start[j]);
       }
     }
   }
@@ -177,7 +184,7 @@ void TracePC::UpdateObservedPCs() {
     auto P = ClangCountersBegin();
     for (size_t Idx = 0; Idx < NumClangCounters; Idx++)
       if (P[Idx])
-        Observe((uintptr_t)Idx);
+        ObservePC((uintptr_t)Idx);
   }
 }
 

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h?rev=311797&r1=311796&r2=311797&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h Fri Aug 25 13:09:25 2017
@@ -82,6 +82,7 @@ class TracePC {
   void SetUseCounters(bool UC) { UseCounters = UC; }
   void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
   void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
+  void SetPrintNewFuncs(bool P) { DoPrintNewFuncs = P; }
   void UpdateObservedPCs();
   template <class Callback> void CollectFeatures(Callback CB) const;
 
@@ -133,6 +134,7 @@ private:
   bool UseCounters = false;
   bool UseValueProfile = false;
   bool DoPrintNewPCs = false;
+  bool DoPrintNewFuncs = false;
 
   struct Module {
     uint32_t *Start, *Stop;
@@ -158,6 +160,7 @@ private:
   uintptr_t *PCs() const;
 
   std::set<uintptr_t> ObservedPCs;
+  std::set<uintptr_t> ObservedFuncs;
 
   ValueBitMap ValueProfileMap;
   uintptr_t InitialStack;

Added: compiler-rt/trunk/test/fuzzer/PrintFuncTest.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/PrintFuncTest.cpp?rev=311797&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/PrintFuncTest.cpp (added)
+++ compiler-rt/trunk/test/fuzzer/PrintFuncTest.cpp Fri Aug 25 13:09:25 2017
@@ -0,0 +1,39 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+extern "C" {
+__attribute__((noinline))
+void FunctionC(const uint8_t *Data, size_t Size) {
+  if (Size > 3 && Data[3] == 'Z') {
+    static bool PrintedOnce = false;
+    if (!PrintedOnce) {
+      std::cout << "BINGO\n";
+      PrintedOnce = true;
+    }
+  }
+}
+
+__attribute__((noinline))
+void FunctionB(const uint8_t *Data, size_t Size) {
+  if (Size > 2 && Data[2] == 'Z')
+    FunctionC(Data, Size);
+}
+__attribute__((noinline))
+void FunctionA(const uint8_t *Data, size_t Size) {
+  if (Size > 1 && Data[1] == 'U')
+    FunctionB(Data, Size);
+}
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  if (Size > 0 && Data[0] == 'F')
+    FunctionA(Data, Size);
+  return 0;
+}
+

Added: compiler-rt/trunk/test/fuzzer/print-func.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/print-func.test?rev=311797&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/print-func.test (added)
+++ compiler-rt/trunk/test/fuzzer/print-func.test Fri Aug 25 13:09:25 2017
@@ -0,0 +1,10 @@
+RUN: %cpp_compiler %S/PrintFuncTest.cpp -o %t
+RUN: %t -seed=1 -runs=100000 2>&1 | FileCheck %s
+RUN: %t -seed=1 -runs=100000 -print_funcs=0 2>&1 | FileCheck %s --check-prefix=NO
+CHECK: NEW_FUNC: {{.*}} FunctionA
+CHECK: NEW_FUNC: {{.*}} FunctionB
+CHECK: NEW_FUNC: {{.*}} FunctionC
+CHECK: BINGO
+
+NO-NOT: NEW_FUNC
+NO: BINGO




More information about the llvm-commits mailing list