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()


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()
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to