[PATCH] D36083: [utils] Add a script that runs clang in LLDB and stops it when a specified diagnostic is emitted

Alex Lorenz via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 31 04:57:30 PDT 2017


arphaman created this revision.

This script is useful while working on and debugging Clang's diagnostics, as you don't have to figure out where the diagnostic is emitted before setting a breakpoint for the emission of that diagnostic.


Repository:
  rL LLVM

https://reviews.llvm.org/D36083

Files:
  utils/debug-diag.py


Index: utils/debug-diag.py
===================================================================
--- /dev/null
+++ utils/debug-diag.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+# This tool allows you to find a backtrace for a reported diagnostic in Clang.
+#
+# To use:
+#  1) Ensure that diagtool is compiled and is up-to-date
+#  2) Invoke the tool:
+#       debug-diag warn_some_warning /path/to/clang -- -cc1 myfile.cpp
+
+import os
+import subprocess
+import sys
+import tempfile
+
+def invokeLLDB(diagCode, clang, args):
+    # Set a breakpoint at the diagnostic
+    command = """breakpoint set -n DiagnosticsEngine::Report
+breakpoint modify -c "DiagID == %d"
+run
+bt""" % (diagCode)
+
+    filename = ""
+    with tempfile.NamedTemporaryFile(delete=False) as f:
+        f.write(command)
+        filename = f.name
+        f.close()
+
+    p = None
+    try:
+        p = subprocess.Popen(["lldb","-s",f.name, clang,"--"] + args)
+        p.wait()
+    except KeyboardInterrupt:
+        print  >>sys.stderr, 'Killing LLDB.'
+        p.terminate()
+        os.unlink(filename)
+    except:
+        os.unlink(filename)
+        raise
+
+def main():
+    import argparse
+
+    description = "Runs clang in a debugger and stops at a breakpoint when the given diagnostic is reported"
+    parser = argparse.ArgumentParser(description=description)
+    parser.add_argument("diag", metavar="diagnostic", nargs=1,
+                        help="name of the diagnostic")
+    parser.add_argument("clang", metavar="clang", nargs=1,
+                        help="path to clang")
+    parser.add_argument("arguments", metavar="arg", nargs="+",
+                        help="command line arguments that should be passed to clang")
+    args = parser.parse_args()
+
+    if args.arguments[0] != "-cc1":
+        # Clang must run in -cc1 to avoid the fork which breaks debugging.
+        # FIXME: Invoke the driver and figure out the -cc1 options.
+        print >>sys.stderr, "The '-cc1' option should be passed to clang"
+        sys.exit(1)
+
+    # Compute the diagnostic code for the given diagnostic.
+    # FIXME: Diagtool binary might have out-of-date ids, when clang's
+    # diagnostics are modified and clang is rebuilt but diagtool wasn't. The
+    # script should try to identify this issue.
+    diagtool = os.path.join(os.path.dirname(args.clang[0]), "diagtool")
+    p = subprocess.Popen([diagtool,'find-diagnostic-id',args.diag[0]],
+                         stdin=subprocess.PIPE,
+                         stdout=subprocess.PIPE)
+    out,_ = p.communicate()
+    diagCode = None
+    try:
+        diagCode = int(out)
+    except ValueError:
+        # diag-tool will report to stderr.
+        sys.exit(1)
+
+    # Use LLDB to run clang and stop at the diagnostic.
+    invokeLLDB(diagCode, args.clang[0], args.arguments)
+
+if __name__ == '__main__':
+    main()


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36083.108901.patch
Type: text/x-patch
Size: 2886 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170731/51b2e4a4/attachment.bin>


More information about the cfe-commits mailing list