-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
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;
}
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)
"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.")
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);
}
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)
return false;
}
+void Fuzzer::TPCUpdateObservedPCs() { TPC.UpdateObservedPCs(); }
+
size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
assert(InFuzzingThread());
*Data = CurrentUnitData;
bool PrintFinalStats = false;
bool PrintCorpusStats = false;
bool PrintCoverage = false;
+ bool PrintFullCoverage = false;
bool DumpCoverage = false;
bool DetectLeaks = true;
int PurgeAllocatorIntervalSec = 1;
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 "
" 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) {
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);
void PrintModuleInfo();
- void PrintCoverage();
+ void PrintCoverage(bool PrintAllCounters);
template<class CallBack>
void IterateCoveredFunctions(CallBack CB);
--- /dev/null
+123457
\ No newline at end of file
--- /dev/null
+# 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]+)*}}