summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/LibFuzzer.rst2
-rw-r--r--llvm/lib/Fuzzer/FuzzerDriver.cpp2
-rw-r--r--llvm/lib/Fuzzer/FuzzerExtFunctions.def2
-rw-r--r--llvm/lib/Fuzzer/FuzzerFlags.def2
-rw-r--r--llvm/lib/Fuzzer/FuzzerInternal.h4
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp24
-rw-r--r--llvm/lib/Fuzzer/test/fuzzer-printcovpcs.test6
7 files changed, 30 insertions, 12 deletions
diff --git a/llvm/docs/LibFuzzer.rst b/llvm/docs/LibFuzzer.rst
index e3cbde01e84..be4eda323ad 100644
--- a/llvm/docs/LibFuzzer.rst
+++ b/llvm/docs/LibFuzzer.rst
@@ -270,6 +270,8 @@ The most important command line options are:
failure (crash, timeout) as ``$(exact_artifact_path)``. This overrides
``-artifact_prefix`` and will not use checksum in the file name. Do not use
the same path for several parallel processes.
+``-print_pcs``
+ If 1, print out newly covered PCs. Defaults to 0.
``-print_final_stats``
If 1, print statistics at exit. Defaults to 0.
``-detect_leaks``
diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp
index e9913e470fd..592c88a319e 100644
--- a/llvm/lib/Fuzzer/FuzzerDriver.cpp
+++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp
@@ -334,7 +334,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Printf("Dictionary: %zd entries\n", Dictionary.size());
bool DoPlainRun = AllInputsAreFiles();
Options.SaveArtifacts = !DoPlainRun;
- Options.PrintNewCovPcs = Flags.print_new_cov_pcs;
+ Options.PrintNewCovPcs = Flags.print_pcs;
Options.PrintFinalStats = Flags.print_final_stats;
Options.TruncateUnits = Flags.truncate_units;
Options.PruneCorpus = Flags.prune_corpus;
diff --git a/llvm/lib/Fuzzer/FuzzerExtFunctions.def b/llvm/lib/Fuzzer/FuzzerExtFunctions.def
index 08b661392ec..e5cb3a7d9bb 100644
--- a/llvm/lib/Fuzzer/FuzzerExtFunctions.def
+++ b/llvm/lib/Fuzzer/FuzzerExtFunctions.def
@@ -40,6 +40,8 @@ EXT_FUNC(__sanitizer_get_total_unique_caller_callee_pairs, size_t, (), false);
EXT_FUNC(__sanitizer_get_total_unique_coverage, size_t, (), true);
EXT_FUNC(__sanitizer_print_memory_profile, int, (size_t), false);
EXT_FUNC(__sanitizer_print_stack_trace, void, (), true);
+EXT_FUNC(__sanitizer_symbolize_pc, void,
+ (void *, const char *fmt, char *out_buf, size_t out_buf_size), false);
EXT_FUNC(__sanitizer_reset_coverage, void, (), true);
EXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);
EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
diff --git a/llvm/lib/Fuzzer/FuzzerFlags.def b/llvm/lib/Fuzzer/FuzzerFlags.def
index 0b313eb6570..c89e75c9f71 100644
--- a/llvm/lib/Fuzzer/FuzzerFlags.def
+++ b/llvm/lib/Fuzzer/FuzzerFlags.def
@@ -71,7 +71,7 @@ FUZZER_FLAG_STRING(exact_artifact_path,
FUZZER_FLAG_INT(drill, 0, "Experimental: fuzz using a single unit as the seed "
"corpus, then merge with the initial corpus")
FUZZER_FLAG_INT(output_csv, 0, "Enable pulse output in CSV format.")
-FUZZER_FLAG_INT(print_new_cov_pcs, 0, "If 1, print out new covered pcs.")
+FUZZER_FLAG_INT(print_pcs, 0, "If 1, print out newly covered PCs.")
FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.")
FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h
index 4917f125842..bac83cf801c 100644
--- a/llvm/lib/Fuzzer/FuzzerInternal.h
+++ b/llvm/lib/Fuzzer/FuzzerInternal.h
@@ -455,6 +455,7 @@ private:
void InterruptCallback();
void MutateAndTestOne();
void ReportNewCoverage(const Unit &U);
+ void PrintNewPCs();
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);
@@ -516,9 +517,10 @@ private:
// Maximum recorded coverage.
Coverage MaxCoverage;
- // For -print_new_cov_pcs
+ // For -print_pcs
uintptr_t* PcBuffer = nullptr;
size_t PcBufferLen = 0;
+ size_t PrevPcBufferPos;
// Need to know our own thread.
static thread_local bool IsMyThread;
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index e992612881a..01692ecfa57 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -441,15 +441,9 @@ void Fuzzer::ShuffleAndMinimize() {
}
bool Fuzzer::UpdateMaxCoverage() {
- uintptr_t PrevPcBufferPos = MaxCoverage.PcBufferPos;
+ PrevPcBufferPos = MaxCoverage.PcBufferPos;
bool Res = RecordMaxCoverage(&MaxCoverage);
- if (Options.PrintNewCovPcs && PrevPcBufferPos != MaxCoverage.PcBufferPos) {
- for (size_t I = PrevPcBufferPos; I < MaxCoverage.PcBufferPos; ++I) {
- Printf("%p\n", PcBuffer[I]);
- }
- }
-
return Res;
}
@@ -566,6 +560,21 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U) {
}
}
+void Fuzzer::PrintNewPCs() {
+ if (Options.PrintNewCovPcs && PrevPcBufferPos != MaxCoverage.PcBufferPos) {
+ for (size_t I = PrevPcBufferPos; I < MaxCoverage.PcBufferPos; ++I) {
+ if (EF->__sanitizer_symbolize_pc) {
+ char PcDescr[1024];
+ EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PcBuffer[I]),
+ "%p %F %L", PcDescr, sizeof(PcDescr));
+ Printf("\tNEW_PC: %s\n", PcDescr);
+ } else {
+ Printf("\tNEW_PC: %p\n", PcBuffer[I]);
+ }
+ }
+ }
+}
+
void Fuzzer::ReportNewCoverage(const Unit &U) {
Corpus.push_back(U);
UpdateCorpusDistribution();
@@ -574,6 +583,7 @@ void Fuzzer::ReportNewCoverage(const Unit &U) {
PrintStatusForNewUnit(U);
WriteToOutputCorpus(U);
NumberOfNewUnitsAdded++;
+ PrintNewPCs();
}
// Finds minimal number of units in 'Extra' that add coverage to 'Initial'.
diff --git a/llvm/lib/Fuzzer/test/fuzzer-printcovpcs.test b/llvm/lib/Fuzzer/test/fuzzer-printcovpcs.test
index 70b22c7a54b..bcc1c4d780b 100644
--- a/llvm/lib/Fuzzer/test/fuzzer-printcovpcs.test
+++ b/llvm/lib/Fuzzer/test/fuzzer-printcovpcs.test
@@ -1,5 +1,7 @@
-RUN: LLVMFuzzer-SimpleTest -print_new_cov_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
-PCS:{{^0x[a-f0-9]+}}
+RUN: LLVMFuzzer-SimpleTest -print_pcs=1 2>&1 | FileCheck %s --check-prefix=PCS
+PCS-NOT: NEW_PC
+PCS:INITED
+PCS:NEW_PC: {{0x[a-f0-9]+}} in LLVMFuzzerTestOneInput {{.*}}SimpleTest.cpp
PCS:NEW
PCS:BINGO
OpenPOWER on IntegriCloud