forked from OSchip/llvm-project
[libFuzzer] add -print_funcs=1 (on bey default): print newly discovered functions during fuzzing
llvm-svn: 311797
This commit is contained in:
parent
1dbb7578ff
commit
2eef816e6e
|
@ -603,6 +603,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||
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;
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -143,11 +143,18 @@ void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue