[llvm] b5d28f3 - [Debugify][OriginalDIMode] Make HTML reporting infrastructure more resilient

Djordje Todorovic via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 29 07:48:36 PDT 2022


Author: Nikola Tesic
Date: 2022-09-29T16:48:06+02:00
New Revision: b5d28f3ea5069540584b7f8fdb67ae2b9f79ce1c

URL: https://github.com/llvm/llvm-project/commit/b5d28f3ea5069540584b7f8fdb67ae2b9f79ce1c
DIFF: https://github.com/llvm/llvm-project/commit/b5d28f3ea5069540584b7f8fdb67ae2b9f79ce1c.diff

LOG: [Debugify][OriginalDIMode] Make HTML reporting infrastructure more resilient

Debugify in OriginalDebugInfo mode (verify-each-debuginfo-preserve), when used
in parallel builds of large projects, can produce incorrect report. More
precisely, simultaneous writes to JSON report file, could form incorrect JSON
objects, which describe found Debug Info bugs.
This patch uses the lock/unlock mechanism to protect JSON report file and also
makes script llvm/utils/llvm-original-di-preservation.py resilient to corrupted
lines in the report file. So, it ensures the creation of HTML report.

Differential Revision: https://reviews.llvm.org/D115616

Added: 
    llvm/test/tools/llvm-original-di-preservation/Inputs/corrupted.json
    llvm/test/tools/llvm-original-di-preservation/Inputs/expected-skipped.html

Modified: 
    llvm/lib/Transforms/Utils/Debugify.cpp
    llvm/test/tools/llvm-original-di-preservation/basic.test
    llvm/utils/llvm-original-di-preservation.py

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp
index 24126b5ab67bd..f17d252f14b6f 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -513,15 +513,19 @@ static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath,
     return;
   }
 
-  OS_FILE << "{\"file\":\"" << FileNameFromCU << "\", ";
+  if (auto L = OS_FILE.lock()) {
+    OS_FILE << "{\"file\":\"" << FileNameFromCU << "\", ";
 
-  StringRef PassName = NameOfWrappedPass != "" ? NameOfWrappedPass : "no-name";
-  OS_FILE << "\"pass\":\"" << PassName << "\", ";
+    StringRef PassName =
+        NameOfWrappedPass != "" ? NameOfWrappedPass : "no-name";
+    OS_FILE << "\"pass\":\"" << PassName << "\", ";
 
-  llvm::json::Value BugsToPrint{std::move(Bugs)};
-  OS_FILE << "\"bugs\": " << BugsToPrint;
+    llvm::json::Value BugsToPrint{std::move(Bugs)};
+    OS_FILE << "\"bugs\": " << BugsToPrint;
 
-  OS_FILE << "}\n";
+    OS_FILE << "}\n";
+  }
+  OS_FILE.close();
 }
 
 bool llvm::checkDebugInfoMetadata(Module &M,

diff  --git a/llvm/test/tools/llvm-original-di-preservation/Inputs/corrupted.json b/llvm/test/tools/llvm-original-di-preservation/Inputs/corrupted.json
new file mode 100644
index 0000000000000..0e067c6aa6d77
--- /dev/null
+++ b/llvm/test/tools/llvm-original-di-preservation/Inputs/corrupted.json
@@ -0,0 +1,10 @@
+{"file":"debug.c", "pass":"Simplify the CFG", "bugs": [[{"action":"drop","fn-name":"debug_class_type_samep","metadata":"dbg-var-intrinsic","name":"pf1"},{"action":"drop","fn-name":"debug_class_type_samep","metadata":"dbg-var-intrinsic","name":"pf2"},{"action":"drop","fn-name":"debug_class_type_samep","metadata":"dbg-var-intrinsic","name":"pv1"},{"action":"drop","fn-name":"debug_class_type_samep","metadata":"dbg-var-intrinsic","name":"pv2"}]]}
+{"file":"debug.c", "pass":"Combine redundant instructions", "bugs": [[{"action":"drop","fn-name":"debug_write_block","metadata":"dbg-var-intrinsic","name":"n"},{"action":"drop","fn-name":"debug_write_block","metadata":"dbg-var-intrinsic","name":"b"}]]}
+{"file":"ieee.c", "pass":"Interprocedural Sparse Conditional Constant Propagation", "bugs": [[{"action":"not-generate","bb-name":"land.lhs.true251","fn-name":"parse_ieee_bb","instr":"br","metadata":"DILocation"},{"action":"not-generate","bb-name":"cond.false70","fn-n{"file":"stabs.c", "pass":"Simplify the CFG", "bugs": [[{"action":"not-generate","bb-name":"land.lhs.true76","fn-name":"parse_stab","instr":"icmp","metadata":"DILocation"}]]}
+ame":"ieee_end_class_type","instr":"br","metadata":"DILocation"},{"action":"not-generate","bb-name":"lor.lhs.false79","fn-name":"ieee_end_class_type","instr":"br","metadata":"DILocation"}]]}
+{"file":"wrstabs.c", "pass":"Simplify the CFG", "bugs": [[{"action":"drop","fn-name":"stab_bool_type","metadata":"dbg-var-intrinsic","name":"tindex"}]]}
+{"file":"prdbg.c", "pass":"Simplify the CFG", "bugs": [[{"action":"drop","fn-name":"pr_tag_type","metadata":"dbg-var-intrinsic","name":"t"},{"action":"drop","fn-name":"pr_tag_type","metadata":"dbg-var-intrinsic","name":"tag"}]]}
+{"file":"objdump.c", "pass":"Simplify the CFG", "bugs": [[{"action":"drop","fn-name":"dump_section_header","metadata":"dbg-var-intrinsic","name":"comma"},{"action":"drop","fn-name":"dump_section_header","metadata":"dbg-var-intrinsic","name":"ls"}]]}
+{"file":"objdump.c", "bad-field": [[{"action":"drop","fn-name":"dump_section_header","metadata":"dbg-var-intrinsic","name":"comma"},{"action":"drop","fn-name":"dump_section_header","metadata":"dbg-var-intrinsic","name":"ls"}]]}
+{"file":"wrstabs.c", "pass":"Simplify the CFG", "bugs": [[{"bad-bug":"stab_function_type"}]]}
+{"file":"wrstabs.c", "pass":"Simplify the CFG", "bugs": [[{"action":"drop","bb-name":"if.end","fn-name":"stab_function_type","instr":"br","metadata":"DILocation"}]]}

diff  --git a/llvm/test/tools/llvm-original-di-preservation/Inputs/expected-skipped.html b/llvm/test/tools/llvm-original-di-preservation/Inputs/expected-skipped.html
new file mode 100644
index 0000000000000..f70ebbf86b0a2
--- /dev/null
+++ b/llvm/test/tools/llvm-original-di-preservation/Inputs/expected-skipped.html
@@ -0,0 +1,182 @@
+ <html>
+  <head>
+  <style>
+  table, th, td {
+    border: 1px solid black;
+  }
+  table.center {
+    margin-left: auto;
+    margin-right: auto;
+  }
+  </style>
+  </head>
+  <body>
+  <table>
+  <caption><b>Location Bugs found by the Debugify</b></caption>
+  <tr>
+      <th>File</th>
+    <th>LLVM Pass Name</th>
+    <th>LLVM IR Instruction</th>
+    <th>Function Name</th>
+    <th>Basic Block Name</th>
+    <th>Action</th>
+  </tr>
+  </tr>
+    <tr>
+    <td>wrstabs.c</td>
+    <td>Simplify the CFG</td>
+    <td>br</td>
+    <td>stab_function_type</td>
+    <td>if.end</td>
+    <td>drop</td>
+    </tr>
+  <tr>
+</table>
+<br>
+<table>
+  <caption><b>Summary of Location Bugs</b></caption>
+  <tr>
+      <th>LLVM Pass Name</th>
+    <th>Number of bugs</th>
+  </tr>
+    <tr>
+    <td>Simplify the CFG</td>
+    <td>1</td>
+    </tr>
+  <tr>
+</table>
+<br>
+<br>
+<table>
+  <caption><b>SP Bugs found by the Debugify</b></caption>
+  <tr>
+      <th>File</th>
+    <th>LLVM Pass Name</th>
+    <th>Function Name</th>
+    <th>Action</th>
+  </tr>
+<tr>
+        <td colspan='4'> No bugs found </td>
+      </tr>
+    </table>
+<br>
+<table>
+  <caption><b>Summary of SP Bugs</b></caption>
+  <tr>
+      <th>LLVM Pass Name</th>
+    <th>Number of bugs</th>
+  </tr>
+  <tr>
+<tr>
+        <td colspan='2'> No bugs found </td>
+      </tr>
+    </table>
+<br>
+<br>
+<table>
+  <caption><b>Variable Location Bugs found by the Debugify</b></caption>
+  <tr>
+      <th>File</th>
+    <th>LLVM Pass Name</th>
+    <th>Variable</th>
+    <th>Function</th>
+    <th>Action</th>
+  </tr>
+  </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Simplify the CFG</td>
+    <td>pf1</td>
+    <td>debug_class_type_samep</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Simplify the CFG</td>
+    <td>pf2</td>
+    <td>debug_class_type_samep</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Simplify the CFG</td>
+    <td>pv1</td>
+    <td>debug_class_type_samep</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Simplify the CFG</td>
+    <td>pv2</td>
+    <td>debug_class_type_samep</td>
+    <td>drop</td>
+    </tr>
+  <tr>
+  </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Combine redundant instructions</td>
+    <td>n</td>
+    <td>debug_write_block</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>debug.c</td>
+    <td>Combine redundant instructions</td>
+    <td>b</td>
+    <td>debug_write_block</td>
+    <td>drop</td>
+    </tr>
+  <tr>
+  </tr>
+    <tr>
+    <td>prdbg.c</td>
+    <td>Simplify the CFG</td>
+    <td>t</td>
+    <td>pr_tag_type</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>prdbg.c</td>
+    <td>Simplify the CFG</td>
+    <td>tag</td>
+    <td>pr_tag_type</td>
+    <td>drop</td>
+    </tr>
+  <tr>
+  </tr>
+    <tr>
+    <td>objdump.c</td>
+    <td>Simplify the CFG</td>
+    <td>comma</td>
+    <td>dump_section_header</td>
+    <td>drop</td>
+    </tr>
+    <tr>
+    <td>objdump.c</td>
+    <td>Simplify the CFG</td>
+    <td>ls</td>
+    <td>dump_section_header</td>
+    <td>drop</td>
+    </tr>
+  <tr>
+</table>
+<br>
+<table>
+  <caption><b>Summary of Variable Location Bugs</b></caption>
+  <tr>
+      <th>LLVM Pass Name</th>
+    <th>Number of bugs</th>
+  </tr>
+    <tr>
+    <td>Combine redundant instructions</td>
+    <td>2</td>
+    </tr>
+    <tr>
+    <td>Simplify the CFG</td>
+    <td>9</td>
+    </tr>
+  <tr>
+</table>
+</body>
+  </html>
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-original-di-preservation/basic.test b/llvm/test/tools/llvm-original-di-preservation/basic.test
index 1d7924ba65ce9..12292f209fe7e 100644
--- a/llvm/test/tools/llvm-original-di-preservation/basic.test
+++ b/llvm/test/tools/llvm-original-di-preservation/basic.test
@@ -1,2 +1,8 @@
-RUN: %llvm-original-di-preservation %p/Inputs/sample.json %t.html
+RUN: %llvm-original-di-preservation %p/Inputs/sample.json %t.html | FileCheck %s
 RUN: 
diff  -w %p/Inputs/expected-sample.html %t.html
+CHECK-NOT: Skipped lines:
+
+RUN: %llvm-original-di-preservation %p/Inputs/corrupted.json %t2.html | FileCheck %s -check-prefix=CORRUPTED
+RUN: 
diff  -w %p/Inputs/expected-skipped.html %t2.html
+CORRUPTED: Skipped lines: 3
+CORRUPTED: Skipped bugs: 1

diff  --git a/llvm/utils/llvm-original-di-preservation.py b/llvm/utils/llvm-original-di-preservation.py
index 0744c3b3452b5..73d7d4bf90cf1 100755
--- a/llvm/utils/llvm-original-di-preservation.py
+++ b/llvm/utils/llvm-original-di-preservation.py
@@ -330,6 +330,7 @@ def generate_html_report(di_location_bugs, di_subprogram_bugs, di_var_bugs, \
 def get_json(file):
   json_parsed = None
   di_checker_data = []
+  skipped_lines = 0
 
   # The file contains json object per line.
   # An example of the line (formatted json):
@@ -356,11 +357,11 @@ def get_json(file):
       try:
         json_object = loads(json_object_line)
       except:
-        print ("error: No valid di-checker data found.")
-        sys.exit(1)
-      di_checker_data.append(json_object)
+        skipped_lines += 1
+      else:
+        di_checker_data.append(json_object)
 
-  return di_checker_data
+  return (di_checker_data, skipped_lines)
 
 # Parse the program arguments.
 def parse_program_args(parser):
@@ -377,7 +378,7 @@ def Main():
     print ("error: The output file must be '.html'.")
     sys.exit(1)
 
-  debug_info_bugs = get_json(opts.file_name)
+  (debug_info_bugs, skipped_lines) = get_json(opts.file_name)
 
   # Use the defaultdict in order to make multidim dicts.
   di_location_bugs = defaultdict(lambda: defaultdict(dict))
@@ -389,24 +390,37 @@ def Main():
   di_sp_bugs_summary = OrderedDict()
   di_var_bugs_summary = OrderedDict()
 
+  skipped_bugs = 0
   # Map the bugs into the file-pass pairs.
   for bugs_per_pass in debug_info_bugs:
-    bugs_file = bugs_per_pass["file"]
-    bugs_pass = bugs_per_pass["pass"]
-
-    bugs = bugs_per_pass["bugs"][0]
+    try:
+      bugs_file = bugs_per_pass["file"]
+      bugs_pass = bugs_per_pass["pass"]
+      bugs = bugs_per_pass["bugs"][0]
+    except:
+      skipped_lines += 1
+      continue
 
     di_loc_bugs = []
     di_sp_bugs = []
     di_var_bugs = []
 
     for bug in bugs:
-      bugs_metadata = bug["metadata"]
+      try:
+        bugs_metadata = bug["metadata"]
+      except:
+        skipped_bugs += 1
+        continue
+
       if bugs_metadata == "DILocation":
-        action = bug["action"]
-        bb_name = bug["bb-name"]
-        fn_name = bug["fn-name"]
-        instr = bug["instr"]
+        try:
+          action = bug["action"]
+          bb_name = bug["bb-name"]
+          fn_name = bug["fn-name"]
+          instr = bug["instr"]
+        except:
+          skipped_bugs += 1
+          continue
         di_loc_bugs.append(DILocBug(action, bb_name, fn_name, instr))
 
         # Fill the summary dict.
@@ -415,8 +429,12 @@ def Main():
         else:
           di_location_bugs_summary[bugs_pass] = 1
       elif bugs_metadata == "DISubprogram":
-        action = bug["action"]
-        name = bug["name"]
+        try:
+          action = bug["action"]
+          name = bug["name"]
+        except:
+          skipped_bugs += 1
+          continue
         di_sp_bugs.append(DISPBug(action, name))
 
         # Fill the summary dict.
@@ -425,9 +443,13 @@ def Main():
         else:
           di_sp_bugs_summary[bugs_pass] = 1
       elif bugs_metadata == "dbg-var-intrinsic":
-        action = bug["action"]
-        fn_name = bug["fn-name"]
-        name = bug["name"]
+        try:
+          action = bug["action"]
+          fn_name = bug["fn-name"]
+          name = bug["name"]
+        except:
+          skipped_bugs += 1
+          continue
         di_var_bugs.append(DIVarBug(action, name, fn_name))
 
         # Fill the summary dict.
@@ -436,8 +458,9 @@ def Main():
         else:
           di_var_bugs_summary[bugs_pass] = 1
       else:
-        print ("error: Unsupported metadata.")
-        sys.exit(1)
+        # Unsupported metadata.
+        skipped_bugs += 1
+        continue
 
     di_location_bugs[bugs_file][bugs_pass] = di_loc_bugs
     di_subprogram_bugs[bugs_file][bugs_pass] = di_sp_bugs
@@ -447,6 +470,11 @@ def Main():
                        di_location_bugs_summary, di_sp_bugs_summary, \
                        di_var_bugs_summary, opts.html_file)
 
+  if skipped_lines > 0:
+    print ("Skipped lines: " + str(skipped_lines))
+  if skipped_bugs > 0:
+    print ("Skipped bugs: " + str(skipped_bugs))
+
 if __name__ == "__main__":
   Main()
   sys.exit(0)


        


More information about the llvm-commits mailing list