[llvm] r281577 - [libFuzzer] implement print_pcs with trace-pc-guard. Change the trace-pc-guard heuristic for 8-bit counters to look more like in AFL (not that it's provable better, but the existin test preferes this heuristic)
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 14 21:36:46 PDT 2016
Author: kcc
Date: Wed Sep 14 23:36:45 2016
New Revision: 281577
URL: http://llvm.org/viewvc/llvm-project?rev=281577&view=rev
Log:
[libFuzzer] implement print_pcs with trace-pc-guard. Change the trace-pc-guard heuristic for 8-bit counters to look more like in AFL (not that it's provable better, but the existin test preferes this heuristic)
Modified:
llvm/trunk/lib/Fuzzer/FuzzerInternal.h
llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h
llvm/trunk/lib/Fuzzer/test/fuzzer-printcovpcs.test
Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=281577&r1=281576&r2=281577&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Wed Sep 14 23:36:45 2016
@@ -365,13 +365,27 @@ class TracePC {
size_t UpdateCounterMap(ValueBitMap *Map);
void FinalizeTrace();
+ size_t GetNewPCsAndFlush(uintptr_t **NewPCsPtr = nullptr) {
+ if (NewPCsPtr)
+ *NewPCsPtr = NewPCs;
+ size_t Res = NumNewPCs;
+ NumNewPCs = 0;
+ return Res;
+ }
+
private:
bool UseCounters = false;
size_t TotalCoverage = 0;
size_t TotalCounterBits = 0;
+ static const size_t kMaxNewPCs = 64;
+ uintptr_t NewPCs[kMaxNewPCs];
+ size_t NumNewPCs = 0;
+ void AddNewPC(uintptr_t PC) { NewPCs[(NumNewPCs++) % kMaxNewPCs] = PC; }
+
uint8_t *Start, *Stop;
ValueBitMap CounterMap;
+ ValueBitMap TotalCoverageMap;
};
extern TracePC TPC;
@@ -469,6 +483,7 @@ private:
void MutateAndTestOne();
void ReportNewCoverage(const Unit &U);
void PrintNewPCs();
+ void PrintOneNewPC(uintptr_t PC);
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
void RunOneAndUpdateCorpus(const uint8_t *Data, size_t Size);
void WriteToOutputCorpus(const Unit &U);
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=281577&r1=281576&r2=281577&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Sep 14 23:36:45 2016
@@ -63,6 +63,7 @@ void Fuzzer::ResetCounters() {
}
if (EF->__sanitizer_get_coverage_pc_buffer_pos)
PcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos();
+ TPC.GetNewPCsAndFlush();
}
void Fuzzer::PrepareCounters(Fuzzer::Coverage *C) {
@@ -556,22 +557,31 @@ void Fuzzer::PrintStatusForNewUnit(const
}
}
+void Fuzzer::PrintOneNewPC(uintptr_t PC) {
+ if (EF->__sanitizer_symbolize_pc) {
+ char PcDescr[1024];
+ EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),
+ "%p %F %L", PcDescr, sizeof(PcDescr));
+ PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
+ Printf("\tNEW_PC: %s\n", PcDescr);
+ } else {
+ Printf("\tNEW_PC: %p\n", PC);
+ }
+}
+
void Fuzzer::PrintNewPCs() {
- if (Options.PrintNewCovPcs && PrevPcBufferPos != PcBufferPos) {
+ if (!Options.PrintNewCovPcs) return;
+ if (PrevPcBufferPos != PcBufferPos) {
int NumPrinted = 0;
for (size_t I = PrevPcBufferPos; I < PcBufferPos; ++I) {
if (NumPrinted++ > 30) break; // Don't print too many new PCs.
- if (EF->__sanitizer_symbolize_pc) {
- char PcDescr[1024];
- EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PcBuffer[I]),
- "%p %F %L", PcDescr, sizeof(PcDescr));
- PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
- Printf("\tNEW_PC: %s\n", PcDescr);
- } else {
- Printf("\tNEW_PC: %p\n", PcBuffer[I]);
- }
+ PrintOneNewPC(PcBuffer[I]);
}
}
+ uintptr_t *PCs;
+ if (size_t NumNewPCs = TPC.GetNewPCsAndFlush(&PCs))
+ for (size_t i = 0; i < NumNewPCs; i++)
+ PrintOneNewPC(PCs[i]);
}
void Fuzzer::ReportNewCoverage(const Unit &U) {
Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=281577&r1=281576&r2=281577&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Wed Sep 14 23:36:45 2016
@@ -21,14 +21,20 @@ TracePC TPC;
void TracePC::HandleTrace(uint8_t *Guard, uintptr_t PC) {
if (UseCounters) {
uintptr_t GV = *Guard;
- if (GV == 0)
- TotalCoverage++;
+ if (GV == 0) {
+ size_t Idx = Guard - Start;
+ if (TotalCoverageMap.AddValue(Idx)) {
+ TotalCoverage++;
+ AddNewPC(PC);
+ }
+ }
if (GV < 255)
GV++;
*Guard = GV;
} else {
*Guard = 0xff;
TotalCoverage++;
+ AddNewPC(PC);
}
}
@@ -43,12 +49,18 @@ void TracePC::FinalizeTrace() {
for (uint8_t *X = Start; X < Stop; X++) {
uint8_t Value = *X;
size_t Idx = X - Start;
- if (Value >= 2) {
- unsigned Bit = 31 - __builtin_clz(Value);
- assert(Bit < 8);
+ if (Value >= 1) {
+ unsigned Bit = 0;
+ /**/ if (Value >= 128) Bit = 7;
+ else if (Value >= 32) Bit = 6;
+ else if (Value >= 16) Bit = 5;
+ else if (Value >= 8) Bit = 4;
+ else if (Value >= 4) Bit = 3;
+ else if (Value >= 3) Bit = 2;
+ else if (Value >= 2) Bit = 1;
CounterMap.AddValue(Idx * 8 + Bit);
}
- *X = 1;
+ *X = 0;
}
}
}
Modified: llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h?rev=281577&r1=281576&r2=281577&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerValueBitMap.h Wed Sep 14 23:36:45 2016
@@ -24,12 +24,16 @@ struct ValueBitMap {
// Clears all bits.
void Reset() { memset(Map, 0, sizeof(Map)); }
- // Computed a hash function of Value and sets the corresponding bit.
- inline void AddValue(uintptr_t Value) {
+ // Computes a hash function of Value and sets the corresponding bit.
+ // Returns true if the bit was changed from 0 to 1.
+ inline bool AddValue(uintptr_t Value) {
uintptr_t Idx = Value < kMapSizeInBits ? Value : Value % kMapSizeInBits;
uintptr_t WordIdx = Idx / kBitsInWord;
uintptr_t BitIdx = Idx % kBitsInWord;
- Map[WordIdx] |= 1UL << BitIdx;
+ uintptr_t Old = Map[WordIdx];
+ uintptr_t New = Old | (1UL << BitIdx);
+ Map[WordIdx] = New;
+ return New != Old;
}
// Merges 'Other' into 'this', clears 'Other',
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer-printcovpcs.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-printcovpcs.test?rev=281577&r1=281576&r2=281577&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-printcovpcs.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-printcovpcs.test Wed Sep 14 23:36:45 2016
@@ -1,7 +1,14 @@
-RUN: LLVMFuzzer-SimpleTest -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
+RUN: LLVMFuzzer-SimpleTest -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
+RUN: LLVMFuzzer-SimpleTest-TracePC -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
PCS-NOT: NEW_PC
PCS:INITED
PCS:NEW_PC: {{0x[a-f0-9]+}}
+PCS:NEW_PC: {{0x[a-f0-9]+}}
PCS:NEW
PCS:BINGO
+RUN: LLVMFuzzer-CounterTest-TracePC -use_counters=0 -print_pcs=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=C_PCS
+RUN: LLVMFuzzer-CounterTest-TracePC -use_counters=1 -print_pcs=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=C_PCS
+
+C_PCS: NEW_PC: {{.*}} in LLVMFuzzerTestOneInput {{.*}}CounterTest.cpp:11
+C_PCS: NEW_PC: {{.*}} in LLVMFuzzerTestOneInput {{.*}}CounterTest.cpp:12
More information about the llvm-commits
mailing list