]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gdbhooks.py: add "break-on-pass" command
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Aug 2014 21:01:47 +0000 (21:01 +0000)
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Aug 2014 21:01:47 +0000 (21:01 +0000)
gcc/
2014-08-05  David Malcolm  <dmalcolm@redhat.com>

        * gdbhooks.py (find_gcc_source_dir): New helper function.
        (class PassNames): New class, locating and parsing passes.def.
        (class BreakOnPass): New command "break-on-pass".

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213646 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gdbhooks.py

index 17a0f2d93c4adf2e7c4cc777d9a6db39f878fa6a..dc7d6a3bc7a624e78a2cca2d1c432851897bc33e 100644 (file)
@@ -1,3 +1,9 @@
+2014-08-05  David Malcolm  <dmalcolm@redhat.com>
+
+        * gdbhooks.py (find_gcc_source_dir): New helper function.
+        (class PassNames): New class, locating and parsing passes.def.
+        (class BreakOnPass): New command "break-on-pass".
+
 2014-08-05  Trevor Saunders  <tsaunders@mozilla.com>
 
        * tree-ssa.c (redirect_edge_var_map_dup): insert newe before
index 85608dca0b0f960fd3e445a4d20eb3be3559bfe3..0af8ecd0056e619563ffd20bc7d7ca1b5df8f16e 100644 (file)
@@ -130,6 +130,7 @@ Instead (for now) you must access m_vecdata:
   (gdb) p bb->preds->m_vecdata[1]
   $21 = <edge 0x7ffff044d3b8 (4 -> 5)>
 """
+import os.path
 import re
 
 import gdb
@@ -476,4 +477,70 @@ gdb.printing.register_pretty_printer(
     gdb.current_objfile(),
     build_pretty_printer())
 
+def find_gcc_source_dir():
+    # Use location of global "g" to locate the source tree
+    sym_g = gdb.lookup_global_symbol('g')
+    path = sym_g.symtab.filename # e.g. '../../src/gcc/context.h'
+    srcdir = os.path.split(path)[0] # e.g. '../../src/gcc'
+    return srcdir
+
+class PassNames:
+    """Parse passes.def, gathering a list of pass class names"""
+    def __init__(self):
+        srcdir = find_gcc_source_dir()
+        self.names = []
+        with open(os.path.join(srcdir, 'passes.def')) as f:
+            for line in f:
+                m = re.match('\s*NEXT_PASS \((.+)\);', line)
+                if m:
+                    self.names.append(m.group(1))
+
+class BreakOnPass(gdb.Command):
+    """
+    A custom command for putting breakpoints on the execute hook of passes.
+    This is largely a workaround for issues with tab-completion in gdb when
+    setting breakpoints on methods on classes within anonymous namespaces.
+
+    Example of use: putting a breakpoint on "final"
+      (gdb) break-on-pass
+    Press <TAB>; it autocompletes to "pass_":
+      (gdb) break-on-pass pass_
+    Press <TAB>:
+      Display all 219 possibilities? (y or n)
+    Press "n"; then type "f":
+      (gdb) break-on-pass pass_f
+    Press <TAB> to autocomplete to pass classnames beginning with "pass_f":
+      pass_fast_rtl_dce              pass_fold_builtins
+      pass_feedback_split_functions  pass_forwprop
+      pass_final                     pass_fre
+      pass_fixup_cfg                 pass_free_cfg
+    Type "in<TAB>" to complete to "pass_final":
+      (gdb) break-on-pass pass_final
+    ...and hit <RETURN>:
+      Breakpoint 6 at 0x8396ba: file ../../src/gcc/final.c, line 4526.
+    ...and we have a breakpoint set; continue execution:
+      (gdb) cont
+      Continuing.
+      Breakpoint 6, (anonymous namespace)::pass_final::execute (this=0x17fb990) at ../../src/gcc/final.c:4526
+      4526       virtual unsigned int execute (function *) { return rest_of_handle_final (); }
+    """
+    def __init__(self):
+        gdb.Command.__init__(self, 'break-on-pass', gdb.COMMAND_BREAKPOINTS)
+        self.pass_names = None
+
+    def complete(self, text, word):
+        # Lazily load pass names:
+        if not self.pass_names:
+            self.pass_names = PassNames()
+
+        return [name
+                for name in sorted(self.pass_names.names)
+                if name.startswith(text)]
+
+    def invoke(self, arg, from_tty):
+        sym = '(anonymous namespace)::%s::execute' % arg
+        breakpoint = gdb.Breakpoint(sym)
+
+BreakOnPass()
+
 print('Successfully loaded GDB hooks for GCC')