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!
(gdb) break *0x972