2

Not a duplicate of this question, as I'm working through the python interface to gdb.
This one is similar but does not have an answer.

I'm extending a gdb.breakpoint in python so that it writes certain registers to file, and then jumps to an address: at 0x4021ee, I want to write stuff to file, then jump to 0x4021f3

However, nothing in command is ever getting executed.

import gdb
class DebugPrintingBreakpoint(gdb.Breakpoint):
    def __init__(self, spec, command):
        super(DebugPrintingBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT, internal = False)
        self.command = command

    def stop(self):
        with open('tracer', 'a') as f:
            f.write(chr(gdb.parse_and_eval("$rbx") ^ 0x71))
            f.close()
        return False



gdb.execute("start")
DebugPrintingBreakpoint("*0x4021ee", "jump *0x4021f3")
gdb.execute("continue")

If I explicitly add gdb.execute(self.command) to the end of stop(), I get Python Exception <class 'gdb.error'> Cannot execute this command while the selected thread is running.:

Anyone have a working example of command lists with breakpoints in python gdb?

Community
  • 1
  • 1
robertkin
  • 179
  • 9

2 Answers2

1

The Breakpoint.stop method is called when, in gdb terms, the inferior is still "executing". Partly this is a bookkeeping oddity -- of course the inferior isn't really executing, it is stopped while gdb does a bit of breakpoint-related processing. Internally it is more like gdb hasn't yet decided to report the stop to other interested parties inside gdb. This funny state is what lets stop work so nicely vis a vis next and other execution commands.

Some commands in gdb can't be invoked while the inferior is running, like jump, as you've found.

One thing you could try -- I have never tried this and don't know if it would work -- would be to assign to the PC in your stop method. This might do the right thing; but of course you should know that the documentation warns against doing weird stuff like this.

Failing that I think the only approach is to fall back to using commands to attach the jump to the breakpoint. This has the drawback that it will interfere with next.

One final way would be to patch the running code to insert a jump or just a sequence of nops.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
1

A couple options to try:

  1. Use gdb.post_event from stop() to run the desired command later. I believe you'll need to return True from your function then call continue from your event.
  2. Create a normal breakpoint and listen to events.stop to check if your breakpoint was hit.
Matt
  • 865
  • 2
  • 10
  • 16