Break if outside of section
Just a little example of how to use gdb.py to create a breakpoint that only fires if called outside of a give section :
int main() { srand(time(NULL)); for (int i = 0; i < 100; i++) { if (rand() > THRESHOLD) do_in_section(0); start(); do_in_section(1); stop(); } }
Functions start() and stop() delimit the section: it is okay to call do_in_section() inside the section. However, every once in a while, do_in_section() is called from outside of this section. (Forget about that boolean flag parameter, it's just for logging and consistency checks. Real-life codes won't have such an easy way to discriminate outside from inside call ... otherwise you don't need an advanced breakpoint!)
(gdb) break do_in_section
will lead to many useless stops, as most of the call to do_in_section() are legal, so what should do is:
- set an internal breakpoint on start(), where we set a flag and continue
- set an internal breakpoint on stop()` where we unset the flag and continue
- set a breakpoint on do_in_section() that checks that flag, and only stop if outside of the section
which gives in Python:
import gdb in_section = False class StartStopBreakpoint(gdb.Breakpoint): def __init__(self, loc, is_start): gdb.Breakpoint.__init__(self, loc, internal=True) self.silent = True self.is_start = is_start def stop(self): global in_section if self.is_start: # I know that this 'if' is not necessary ... assert not in_section in_section = True else: assert in_section in_section = False return False # never stop here class SectionBreakpoint(gdb.Breakpoint): def __init__(self, location): gdb.Breakpoint.__init__(self, location, internal=True) self.silent = True def stop(self): if in_section: print("ignore hit in section") assert gdb.parse_and_eval("inside") == 1 return False else: print("") print("Section breakpoint hit outside of section") print("") assert gdb.parse_and_eval("inside") == 0 return True StartStopBreakpoint("start", is_start=True) StartStopBreakpoint("stop", is_start=False) SectionBreakpoint("do_in_section")
Just source that file, or input it in GDB python commandline. The three last line instantiate the breakpoints:
$ gdb -ex "source test.py" a.out GNU gdb (GDB) 7.10.50.20160122-git ... (gdb) run Starting program: /home/kevin/a.out ignore ignore .... Section breakpoint hit outside of section (gdb) print inside $1 = 0
Et voila!