[llvm] r262073 - [libFuzzer] initial implementation of path coverage based on -fsanitize-coverage=trace-pc. This does not scale well yet, but already cracks FullCoverageSetTest in seconds

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 13:33:56 PST 2016


Author: kcc
Date: Fri Feb 26 15:33:56 2016
New Revision: 262073

URL: http://llvm.org/viewvc/llvm-project?rev=262073&view=rev
Log:
[libFuzzer] initial implementation of path coverage based on -fsanitize-coverage=trace-pc. This does not scale well yet, but already cracks FullCoverageSetTest in seconds

Added:
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Fuzzer/test/fuzzer-trace-pc.test
    llvm/trunk/lib/Fuzzer/test/trace-pc/
    llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt
Modified:
    llvm/trunk/lib/Fuzzer/CMakeLists.txt
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/test/CMakeLists.txt

Modified: llvm/trunk/lib/Fuzzer/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=262073&r1=262072&r2=262073&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/CMakeLists.txt Fri Feb 26 15:33:56 2016
@@ -12,6 +12,7 @@ if( LLVM_USE_SANITIZE_COVERAGE )
     FuzzerMutate.cpp
     FuzzerSanitizerOptions.cpp
     FuzzerSHA1.cpp
+    FuzzerTracePC.cpp
     FuzzerUtil.cpp
     )
   add_library(LLVMFuzzerNoMain STATIC

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=262073&r1=262072&r2=262073&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Feb 26 15:33:56 2016
@@ -99,6 +99,13 @@ bool IsASCII(const Unit &U);
 int NumberOfCpuCores();
 int GetPid();
 
+// Clears the current PC Map.
+void PcMapResetCurrent();
+// Merges the current PC Map into the combined one, and clears the former.
+void PcMapMergeCurrentToCombined();
+// Returns the size of the combined PC Map.
+size_t PcMapCombinedSize();
+
 class Random {
  public:
   Random(unsigned int seed) : R(seed) {}
@@ -390,6 +397,7 @@ private:
   long TimeOfLongestUnitInSeconds = 0;
   long EpochOfLastReadOfOutputCorpus = 0;
   size_t LastRecordedBlockCoverage = 0;
+  size_t LastRecordedPcMapSize = 0;
   size_t LastRecordedCallerCalleeCoverage = 0;
   size_t LastCoveragePcBufferLen = 0;
 };

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=262073&r1=262072&r2=262073&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri Feb 26 15:33:56 2016
@@ -151,6 +151,8 @@ void Fuzzer::PrintStats(const char *Wher
   Printf("#%zd\t%s", TotalNumberOfRuns, Where);
   if (LastRecordedBlockCoverage)
     Printf(" cov: %zd", LastRecordedBlockCoverage);
+  if (LastRecordedPcMapSize)
+    Printf(" path: %zd", LastRecordedPcMapSize);
   if (auto TB = TotalBits())
     Printf(" bits: %zd", TB);
   if (LastRecordedCallerCalleeCoverage)
@@ -316,6 +318,12 @@ bool Fuzzer::CheckCoverageAfterRun() {
   size_t OldCallerCalleeCoverage = LastRecordedCallerCalleeCoverage;
   size_t NewCallerCalleeCoverage = RecordCallerCalleeCoverage();
   size_t NumNewBits = 0;
+  size_t OldPcMapSize = LastRecordedPcMapSize;
+  PcMapMergeCurrentToCombined();
+  size_t NewPcMapSize = PcMapCombinedSize();
+  LastRecordedPcMapSize = NewPcMapSize;
+  if (NewPcMapSize > OldPcMapSize)
+    return true;
   if (Options.UseCounters)
     NumNewBits = __sanitizer_update_counter_bitset_and_clear_counters(
         CounterBitmap.data());

Added: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=262073&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (added)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Fri Feb 26 15:33:56 2016
@@ -0,0 +1,59 @@
+//===- FuzzerTracePC.cpp - PC tracing--------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Trace PCs.
+// This module implements __sanitizer_cov_trace_pc, a callback required
+// for -fsanitize-coverage=trace-pc instrumentation.
+//
+// Experimental and not yet tuned for performance.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerInternal.h"
+
+namespace fuzzer {
+static const size_t kMapSize = 65371; // Prime.
+static uint8_t CurMap[kMapSize];
+static uint8_t CombinedMap[kMapSize];
+static size_t CombinedMapSize;
+static thread_local uintptr_t Prev;
+
+void PcMapResetCurrent() {
+  if (Prev) {
+    Prev = 0;
+    memset(CurMap, 0, sizeof(CurMap));
+  }
+}
+
+// TODO: speed this up.
+void PcMapMergeCurrentToCombined() {
+  if (!Prev) return;
+  uintptr_t Res = 0;
+  for (size_t i = 0; i < kMapSize; i++) {
+    uint8_t p = (CombinedMap[i] |= CurMap[i]);
+    CurMap[i] = 0;
+    Res += p != 0;
+  }
+  CombinedMapSize = Res;
+}
+
+size_t PcMapCombinedSize() { return CombinedMapSize; }
+
+static void HandlePC(uintptr_t PC) {
+  // We take 12 bits of PC and mix it with the previous PCs.
+  uintptr_t Idx = (Prev << 5) ^ (PC & 4095);
+  CurMap[Idx % kMapSize] = 1;
+  Prev = Idx;
+}
+
+} // namespace fuzzer
+
+extern "C" void __sanitizer_cov_trace_pc() {
+  fuzzer::HandlePC(reinterpret_cast<uintptr_t>(__builtin_return_address(0)));
+}
+//uintptr_t __sanitizer_get_total_unique_coverage() { return 0; }
+//uintptr_t __sanitizer_get_number_of_counters() { return 0; }

Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=262073&r1=262072&r2=262073&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Fri Feb 26 15:33:56 2016
@@ -47,6 +47,11 @@ set(TraceBBTests
   SimpleTest
   )
 
+set(TracePCTests
+  FourIndependentBranchesTest
+  FullCoverageSetTest
+  )
+
 set(TestBinaries)
 
 foreach(Test ${Tests})
@@ -113,6 +118,12 @@ foreach(Test ${TraceBBTests})
   set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-TraceBB)
 endforeach()
 
+add_subdirectory(trace-pc)
+
+foreach(Test ${TracePCTests})
+  set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-TracePC)
+endforeach()
+
 set_target_properties(${TestBinaries}
   PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   )

Added: llvm/trunk/lib/Fuzzer/test/fuzzer-trace-pc.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-trace-pc.test?rev=262073&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-trace-pc.test (added)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-trace-pc.test Fri Feb 26 15:33:56 2016
@@ -0,0 +1,2 @@
+CHECK: BINGO
+RUN: not LLVMFuzzer-FourIndependentBranchesTest-TracePC      -seed=1 -runs=1000000 2>&1 | FileCheck %s

Added: llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt?rev=262073&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt (added)
+++ llvm/trunk/lib/Fuzzer/test/trace-pc/CMakeLists.txt Fri Feb 26 15:33:56 2016
@@ -0,0 +1,14 @@
+# These tests are not instrumented with coverage.
+
+set(CMAKE_CXX_FLAGS_RELEASE
+  "${LIBFUZZER_FLAGS_BASE} -O0 -fno-sanitize-coverage=8bit-counters -fsanitize-coverage=trace-pc")
+
+foreach(Test ${TracePCTests})
+  add_executable(LLVMFuzzer-${Test}-TracePC
+    ../${Test}.cpp
+    )
+  target_link_libraries(LLVMFuzzer-${Test}-TracePC
+    LLVMFuzzer
+    )
+endforeach()
+




More information about the llvm-commits mailing list