[compiler-rt] dc62d5e - [libFuzzer] Added -print_full_coverage flag.
Max Moroz via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 23 16:09:23 PDT 2020
Author: Max Moroz
Date: 2020-10-23T16:05:54-07:00
New Revision: dc62d5ec97261429b553f2d6b45d96a137211f14
URL: https://github.com/llvm/llvm-project/commit/dc62d5ec97261429b553f2d6b45d96a137211f14
DIFF: https://github.com/llvm/llvm-project/commit/dc62d5ec97261429b553f2d6b45d96a137211f14.diff
LOG: [libFuzzer] Added -print_full_coverage flag.
-print_full_coverage=1 produces a detailed branch coverage dump when run on a single file.
Uses same infrastructure as -print_coverage flag, but prints all branches (regardless of coverage status) in an easy-to-parse format.
Usage: For internal use with machine learning fuzzing models which require detailed coverage information on seed files to generate mutations.
Differential Revision: https://reviews.llvm.org/D85928
Added:
compiler-rt/test/fuzzer/dso-cov-input.txt
compiler-rt/test/fuzzer/full-coverage.test
Modified:
compiler-rt/lib/fuzzer/FuzzerDriver.cpp
compiler-rt/lib/fuzzer/FuzzerFlags.def
compiler-rt/lib/fuzzer/FuzzerInternal.h
compiler-rt/lib/fuzzer/FuzzerLoop.cpp
compiler-rt/lib/fuzzer/FuzzerOptions.h
compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
compiler-rt/lib/fuzzer/FuzzerTracePC.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index 83ef642ceeb6..6b674c4e9d7a 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -321,7 +321,12 @@ int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
if (MaxLen && MaxLen < U.size())
U.resize(MaxLen);
F->ExecuteCallback(U.data(), U.size());
- F->TryDetectingAMemoryLeak(U.data(), U.size(), true);
+ if (Flags.print_full_coverage) {
+ // Leak detection is not needed when collecting full coverage data.
+ F->TPCUpdateObservedPCs();
+ } else {
+ F->TryDetectingAMemoryLeak(U.data(), U.size(), true);
+ }
return 0;
}
@@ -743,6 +748,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.PrintFinalStats = Flags.print_final_stats;
Options.PrintCorpusStats = Flags.print_corpus_stats;
Options.PrintCoverage = Flags.print_coverage;
+ Options.PrintFullCoverage = Flags.print_full_coverage;
if (Flags.exit_on_src_pos)
Options.ExitOnSrcPos = Flags.exit_on_src_pos;
if (Flags.exit_on_item)
diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def
index 4d4841b17ae4..ef6c3f8ba8f0 100644
--- a/compiler-rt/lib/fuzzer/FuzzerFlags.def
+++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def
@@ -132,6 +132,8 @@ FUZZER_FLAG_INT(print_corpus_stats, 0,
"If 1, print statistics on corpus elements at exit.")
FUZZER_FLAG_INT(print_coverage, 0, "If 1, print coverage information as text"
" at exit.")
+FUZZER_FLAG_INT(print_full_coverage, 0, "If 1, print full coverage information "
+ "(all branches) as text at exit.")
FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated.")
FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.")
diff --git a/compiler-rt/lib/fuzzer/FuzzerInternal.h b/compiler-rt/lib/fuzzer/FuzzerInternal.h
index 2b172d912227..37c8a01dc3c6 100644
--- a/compiler-rt/lib/fuzzer/FuzzerInternal.h
+++ b/compiler-rt/lib/fuzzer/FuzzerInternal.h
@@ -69,6 +69,7 @@ class Fuzzer {
bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
InputInfo *II = nullptr, bool ForceAddToCorpus = false,
bool *FoundUniqFeatures = nullptr);
+ void TPCUpdateObservedPCs();
// Merge Corpora[1:] into Corpora[0].
void Merge(const Vector<std::string> &Corpora);
diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
index f1895ec2621a..6e3bf44f8b45 100644
--- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
@@ -354,8 +354,10 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units,
}
void Fuzzer::PrintFinalStats() {
+ if (Options.PrintFullCoverage)
+ TPC.PrintCoverage(/*PrintAllCounters=*/true);
if (Options.PrintCoverage)
- TPC.PrintCoverage();
+ TPC.PrintCoverage(/*PrintAllCounters=*/false);
if (Options.PrintCorpusStats)
Corpus.PrintStats();
if (!Options.PrintFinalStats)
@@ -545,6 +547,8 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
return false;
}
+void Fuzzer::TPCUpdateObservedPCs() { TPC.UpdateObservedPCs(); }
+
size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
assert(InFuzzingThread());
*Data = CurrentUnitData;
diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h
index 20b810b2867f..21155e9c5692 100644
--- a/compiler-rt/lib/fuzzer/FuzzerOptions.h
+++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h
@@ -68,6 +68,7 @@ struct FuzzingOptions {
bool PrintFinalStats = false;
bool PrintCorpusStats = false;
bool PrintCoverage = false;
+ bool PrintFullCoverage = false;
bool DumpCoverage = false;
bool DetectLeaks = true;
int PurgeAllocatorIntervalSec = 1;
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
index b2ca7693e540..91e94d824002 100644
--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
@@ -269,7 +269,7 @@ bool TracePC::ObservedFocusFunction() {
return FocusFunctionCounterPtr && *FocusFunctionCounterPtr;
}
-void TracePC::PrintCoverage() {
+void TracePC::PrintCoverage(bool PrintAllCounters) {
if (!EF->__sanitizer_symbolize_pc ||
!EF->__sanitizer_get_module_and_offset_for_pc) {
Printf("INFO: __sanitizer_symbolize_pc or "
@@ -277,7 +277,7 @@ void TracePC::PrintCoverage() {
" not printing coverage\n");
return;
}
- Printf("COVERAGE:\n");
+ Printf(PrintAllCounters ? "FULL COVERAGE:\n" : "COVERAGE:\n");
auto CoveredFunctionCallback = [&](const PCTableEntry *First,
const PCTableEntry *Last,
uintptr_t Counter) {
@@ -292,17 +292,33 @@ void TracePC::PrintCoverage() {
std::string LineStr = DescribePC("%l", VisualizePC);
size_t NumEdges = Last - First;
Vector<uintptr_t> UncoveredPCs;
+ Vector<uintptr_t> CoveredPCs;
for (auto TE = First; TE < Last; TE++)
if (!ObservedPCs.count(TE))
UncoveredPCs.push_back(TE->PC);
- Printf("%sCOVERED_FUNC: hits: %zd", Counter ? "" : "UN", Counter);
- Printf(" edges: %zd/%zd", NumEdges - UncoveredPCs.size(), NumEdges);
- Printf(" %s %s:%s\n", FunctionStr.c_str(), FileStr.c_str(),
- LineStr.c_str());
- if (Counter)
+ else
+ CoveredPCs.push_back(TE->PC);
+
+ if (PrintAllCounters) {
+ Printf("U");
for (auto PC : UncoveredPCs)
- Printf(" UNCOVERED_PC: %s\n",
- DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
+ Printf(DescribePC(" %l", GetNextInstructionPc(PC)).c_str());
+ Printf("\n");
+
+ Printf("C");
+ for (auto PC : CoveredPCs)
+ Printf(DescribePC(" %l", GetNextInstructionPc(PC)).c_str());
+ Printf("\n");
+ } else {
+ Printf("%sCOVERED_FUNC: hits: %zd", Counter ? "" : "UN", Counter);
+ Printf(" edges: %zd/%zd", NumEdges - UncoveredPCs.size(), NumEdges);
+ Printf(" %s %s:%s\n", FunctionStr.c_str(), FileStr.c_str(),
+ LineStr.c_str());
+ if (Counter)
+ for (auto PC : UncoveredPCs)
+ Printf(" UNCOVERED_PC: %s\n",
+ DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
+ }
};
IterateCoveredFunctions(CoveredFunctionCallback);
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.h b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
index 4601300cb9dc..00909230731d 100644
--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.h
+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
@@ -94,7 +94,7 @@ class TracePC {
void PrintModuleInfo();
- void PrintCoverage();
+ void PrintCoverage(bool PrintAllCounters);
template<class CallBack>
void IterateCoveredFunctions(CallBack CB);
diff --git a/compiler-rt/test/fuzzer/dso-cov-input.txt b/compiler-rt/test/fuzzer/dso-cov-input.txt
new file mode 100644
index 000000000000..6db78894e3e7
--- /dev/null
+++ b/compiler-rt/test/fuzzer/dso-cov-input.txt
@@ -0,0 +1 @@
+123457
\ No newline at end of file
diff --git a/compiler-rt/test/fuzzer/full-coverage.test b/compiler-rt/test/fuzzer/full-coverage.test
new file mode 100644
index 000000000000..688332d5877c
--- /dev/null
+++ b/compiler-rt/test/fuzzer/full-coverage.test
@@ -0,0 +1,15 @@
+# FIXME: Disabled on Windows because -fPIC cannot be used to compile for Windows.
+UNSUPPORTED: windows
+XFAIL: s390x
+RUN: %cpp_compiler %S/DSO1.cpp -fPIC %ld_flags_rpath_so1 -O0 -shared -o %dynamiclib1
+RUN: %cpp_compiler %S/DSO2.cpp -fPIC %ld_flags_rpath_so2 -O0 -shared -o %dynamiclib2
+RUN: %cpp_compiler %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
+
+RUN: %run %t-DSOTest -print_full_coverage=1 %S/dso-cov-input.txt 2>&1 | FileCheck %s
+CHECK: FULL COVERAGE:
+CHECK-DAG: U{{( [0-9]+)*}}
+CHECK-DAG: C{{( [0-9]+)*}}
+CHECK-DAG: U{{( [0-9]+)*}}
+CHECK-DAG: U{{( [0-9]+)*}}
+CHECK-DAG: C{{( [0-9]+)*}}
+CHECK-DAG: U{{( [0-9]+)*}}
More information about the llvm-commits
mailing list