[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