diff options
author | David Malcolm <dmalcolm@redhat.com> | 2014-08-05 21:01:47 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2014-08-05 21:01:47 +0000 |
commit | 17ef89b220b7b0c157899cb93966f4b9af0bea7a (patch) | |
tree | c61b33f7b87037cc4ec306e013ce7125191d6d58 /gcc/gdbhooks.py | |
parent | 6ef6945c9cbb0ab43f3b04e97f0a2285494a9c87 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/gdbhooks.py')
-rw-r--r-- | gcc/gdbhooks.py | 67 |
1 files changed, 67 insertions, 0 deletions
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') |