[compiler-rt] r360272 - [libFuzzer] DFT: when dumping coverage, also dump the total number of instrumented blocks in a function; update merge_data_flow.py to merge coverage
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Wed May 8 10:20:09 PDT 2019
Author: kcc
Date: Wed May 8 10:20:09 2019
New Revision: 360272
URL: http://llvm.org/viewvc/llvm-project?rev=360272&view=rev
Log:
[libFuzzer] DFT: when dumping coverage, also dump the total number of instrumented blocks in a function; update merge_data_flow.py to merge coverage
Modified:
compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp
compiler-rt/trunk/lib/fuzzer/dataflow/DataFlow.cpp
compiler-rt/trunk/lib/fuzzer/scripts/merge_data_flow.py
compiler-rt/trunk/test/fuzzer/dataflow.test
Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp?rev=360272&r1=360271&r2=360272&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp Wed May 8 10:20:09 2019
@@ -52,6 +52,8 @@ void DataFlowTrace::Init(const std::stri
// Printf("=== %s\n", Name.c_str());
std::ifstream IF(SF.File);
while (std::getline(IF, L, '\n')) {
+ if (!L.empty() && L[0] == 'C')
+ continue; // Ignore coverage.
size_t SpacePos = L.find(' ');
if (SpacePos == std::string::npos)
return ParseError("no space in the trace line");
Modified: compiler-rt/trunk/lib/fuzzer/dataflow/DataFlow.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/dataflow/DataFlow.cpp?rev=360272&r1=360271&r2=360272&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/dataflow/DataFlow.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/dataflow/DataFlow.cpp Wed May 8 10:20:09 2019
@@ -44,14 +44,15 @@
// ===============
// F0 11111111111111
// F1 10000000000000
-// C0 1 2 3 4
-// C1
+// C0 1 2 3 4 5
+// C1 8
// ===============
// "FN xxxxxxxxxx": tells what bytes of the input does the function N depend on.
// The byte string is LEN+1 bytes. The last byte is set if the function
// depends on the input length.
-// "CN X Y Z": tells that a function N has basic blocks X, Y, and Z covered
-// in addition to the function's entry block.
+// "CN X Y Z T": tells that a function N has basic blocks X, Y, and Z covered
+// in addition to the function's entry block, out of T total instrumented
+// blocks.
//
//===----------------------------------------------------------------------===*/
@@ -87,6 +88,10 @@ enum {
PCFLAG_FUNC_ENTRY = 1,
};
+static inline bool BlockIsEntry(size_t BlockIdx) {
+ return PCsBeg[BlockIdx * 2 + 1] & PCFLAG_FUNC_ENTRY;
+}
+
// Prints all instrumented functions.
static int PrintFunctions() {
// We don't have the symbolizer integrated with dfsan yet.
@@ -99,8 +104,7 @@ static int PrintFunctions() {
"| sed 's/dfs\\$//g'", "w");
for (size_t I = 0; I < NumGuards; I++) {
uintptr_t PC = PCsBeg[I * 2];
- uintptr_t PCFlags = PCsBeg[I * 2 + 1];
- if (!(PCFlags & PCFLAG_FUNC_ENTRY)) continue;
+ if (!BlockIsEntry(I)) continue;
void *const Buf[1] = {(void*)PC};
backtrace_symbols_fd(Buf, 1, fileno(Pipe));
}
@@ -142,23 +146,22 @@ static void PrintDataFlow(FILE *Out) {
static void PrintCoverage(FILE *Out) {
ssize_t CurrentFuncGuard = -1;
ssize_t CurrentFuncNum = -1;
- int NumFuncsCovered = 0;
- for (size_t I = 0; I < NumGuards; I++) {
- bool IsEntry = PCsBeg[I * 2 + 1] & PCFLAG_FUNC_ENTRY;
- if (IsEntry) {
- CurrentFuncNum++;
- CurrentFuncGuard = I;
- }
- if (!BBExecuted[I]) continue;
- if (IsEntry) {
- if (NumFuncsCovered) fprintf(Out, "\n");
- fprintf(Out, "C%zd ", CurrentFuncNum);
- NumFuncsCovered++;
- } else {
- fprintf(Out, "%zd ", I - CurrentFuncGuard);
+ ssize_t NumBlocksInCurrentFunc = -1;
+ for (size_t FuncBeg = 0; FuncBeg < NumGuards;) {
+ CurrentFuncNum++;
+ assert(BlockIsEntry(FuncBeg));
+ size_t FuncEnd = FuncBeg + 1;
+ for (; FuncEnd < NumGuards && !BlockIsEntry(FuncEnd); FuncEnd++)
+ ;
+ if (BBExecuted[FuncBeg]) {
+ fprintf(Out, "C%zd", CurrentFuncNum);
+ for (size_t I = FuncBeg + 1; I < FuncEnd; I++)
+ if (BBExecuted[I])
+ fprintf(Out, " %zd", I - FuncBeg);
+ fprintf(Out, " %zd\n", FuncEnd - FuncBeg);
}
+ FuncBeg = FuncEnd;
}
- fprintf(Out, "\n");
}
int main(int argc, char **argv) {
@@ -229,7 +232,7 @@ void __sanitizer_cov_pcs_init(const uint
PCsEnd = pcs_end;
assert(NumGuards == (PCsEnd - PCsBeg) / 2);
for (size_t i = 0; i < NumGuards; i++) {
- if (PCsBeg[i * 2 + 1] & PCFLAG_FUNC_ENTRY) {
+ if (BlockIsEntry(i)) {
NumFuncs++;
GuardsBeg[i] = NumFuncs;
}
Modified: compiler-rt/trunk/lib/fuzzer/scripts/merge_data_flow.py
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/scripts/merge_data_flow.py?rev=360272&r1=360271&r2=360272&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/scripts/merge_data_flow.py (original)
+++ compiler-rt/trunk/lib/fuzzer/scripts/merge_data_flow.py Wed May 8 10:20:09 2019
@@ -22,20 +22,37 @@ def Merge(a, b):
def main(argv):
D = {}
+ C = {}
+ # read the lines.
for line in fileinput.input():
+ # collect the coverage.
if line.startswith('C'):
+ COV = line.strip().split(' ')
+ F = COV[0];
+ if not F in C:
+ C[F] = {0}
+ for B in COV[1:]:
+ C[F].add(int(B))
continue
+ # collect the data flow trace.
[F,BV] = line.strip().split(' ')
if F in D:
D[F] = Merge(D[F], BV)
else:
D[F] = BV;
+ # print the combined data flow trace.
for F in D.keys():
if isinstance(D[F], str):
value = D[F]
else:
value = D[F].decode('utf-8')
print("%s %s" % (F, value))
+ # print the combined coverage
+ for F in C.keys():
+ print("%s" % F, end="")
+ for B in list(C[F])[1:]:
+ print(" %s" % B, end="")
+ print()
if __name__ == '__main__':
main(sys.argv)
Modified: compiler-rt/trunk/test/fuzzer/dataflow.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/dataflow.test?rev=360272&r1=360271&r2=360272&view=diff
==============================================================================
--- compiler-rt/trunk/test/fuzzer/dataflow.test (original)
+++ compiler-rt/trunk/test/fuzzer/dataflow.test Wed May 8 10:20:09 2019
@@ -94,8 +94,8 @@ RUN: %libfuzzer_src/scripts/collect_data
RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0 -focus_function=Func2 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE
USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT
-USE_DATA_FLOW_TRACE-DAG: a8eefe2fd5d6b32028f355fafa3e739a6bf5edc => |000001|
-USE_DATA_FLOW_TRACE-DGA: d28cb407e8e1a702c72d25473f0553d3ec172262 => |0000011|
+USE_DATA_FLOW_TRACE-DAG: ca8eefe2fd5d6b32028f355fafa3e739a6bf5edc => |000001|
+USE_DATA_FLOW_TRACE-DAG: d28cb407e8e1a702c72d25473f0553d3ec172262 => |0000011|
USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 2 traces with focus function
# Test that we can run collect_data_flow on a long input (>2**16 bytes)
More information about the llvm-commits
mailing list