aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2014-08-05 21:01:47 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2014-08-05 21:01:47 +0000
commit17ef89b220b7b0c157899cb93966f4b9af0bea7a (patch)
treec61b33f7b87037cc4ec306e013ce7125191d6d58
parent6ef6945c9cbb0ab43f3b04e97f0a2285494a9c87 (diff)
downloadgcc-17ef89b220b7b0c157899cb93966f4b9af0bea7a.zip
gcc-17ef89b220b7b0c157899cb93966f4b9af0bea7a.tar.gz
gcc-17ef89b220b7b0c157899cb93966f4b9af0bea7a.tar.bz2
gdbhooks.py: add "break-on-pass" command
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". From-SVN: r213646
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gdbhooks.py67
2 files changed, 73 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 17a0f2d..dc7d6a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 85608dc..0af8ecd 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -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')