4

Is it possible to control gdb from the debugged program? I'm hoping for a library that can help with this, ideally with an API such as gdb_sendcmd("bt"), but I can live with something like connecting to local gdb via a socket.

Primary use case is programmatically adding a data breakpoint to monitor when a certain memory address next gets modified. Target language is, naturally, C; anything applicable to it can be reused with C++ and Objective-C.


Answer from Employed Russian has solved my direct problem, but I'd still love to know how I can run GDB commands programmatically from the debugged program. It may speed up some debugging if I could simply add code to the project instead of writing extra startup commands for GDB that would create breakpoints with attached commands.

So if there is a way to run commands programmatically, I'd still love to hear it ;)

Community
  • 1
  • 1
Ivan Vučica
  • 9,529
  • 9
  • 60
  • 111
  • I'm pretty sure this can't be done. You can write some scripts for GDB in Python, apparently, but how to automatically invoke them, say, when a breakpoint is hit, to create that memory watch you are asking for, is not clear to me. – MK. Jan 26 '12 at 22:28
  • Many CPU architectures have HW support for this kind of thing with data breakpoints, data watchpoints, instructions that cause breaks, etc. – TJD Jan 26 '12 at 22:55
  • @TJD Exactly -- but I wanted to know how to trigger setting data breakpoint programmatically in gdb, or how to run any other command. – Ivan Vučica Jan 27 '12 at 14:36

2 Answers2

2

The Python interface exported by GDB allows you to do many things. Maybe something like this would fit your requirements:

import gdb

CMD_FCT  = "gdb_run" 
CMD_NAME = "str"

class GdbRunBreakpoint(gdb.Breakpoint):
    def __init__(self):
        gdb.Breakpoint.__init__(self, CMD_FCT, internal=1)
        self.silent = True

    def stop(self):
        cmd = gdb.parse_and_eval(CMD_NAME).string()
        gdb.execute(cmd)
        return False
GdbRunBreakpoint()

(just write than in a file, and source it from your .gdbinit file)

and on the application side:

void gdb_run(char *str) {}


int main () {
    gdb_run("where");
}

I think the code is straight forward, but as I mentioned in https://stackoverflow.com/a/8884512/341106, not everything is allowed in the stop callback, GDB is in an intermediate state, but many things will work as expected.

EDIT: needless to say, this won't work if you app is not compiled with debug symbols!

Community
  • 1
  • 1
Kevin
  • 4,618
  • 3
  • 38
  • 61
  • I'm accepting the answer, despite being unable to actually get this to work on OS X. This is probably due to GDB shipping with Xcode 4 being 6.3.5, while I see you mentioned 7.4 in your other answer. Hence, Python is probably unsupported: `.gdbinit:1: Error in sourced command file:helper.py:3: Error in sourced command file:Undefined command: "import". Try "help".`. I do understand what's going on, though, and it seems to be exactly what I wanted. Thanks! – Ivan Vučica Feb 06 '12 at 17:08
  • 1
    @Ivan oh yeah, 6.3 is a bit old, Nov 2004 according to their website, the Python support was introduced 5 years after ;) – Kevin Feb 06 '12 at 18:43
  • Side note, gdb.execute accepts a \n-separated string to execute multiple commands too. Convenient in this case. // Also if you want to run in the frame of the caller, add a `up` in the code. – user202729 Mar 10 '22 at 05:00
1

Is it possible to control gdb from the debugged program?

No. If the program could do that, and (say) disabled all breakpoints, how would you debug it?

Primary use case is programmatically adding a data breakpoint to monitor when a certain memory address next gets modified.

This often comes up in a context like this: on Nth invocation of foo(), a (local or global) variable bar gets unexpectedly clobbered, and you want to find the culprit.

If that is indeed your problem, then set a breakpoint on the line where you know the value of bar is still good (just after it has been initialized). Set ignore count (using ignore command) on that breakpoint to N-1, and then, when the breakpoint is hit, set the watchpoint on bar.

You can even attach commands to the breakpoint:

commands 1   # assuming this was the first breakpoint
 watch bar
 continue
end

so the watchpoint is attached automatically.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • 1
    Program being allowed to drive gdb (and possibly disable breakpoints) isn't an issue for me during development; having inserted function call that disabled breakpoints, I can also easily remove it. *However*, your idea of attaching commands to breakpoints sounds interesting and solves my problem. I'd still love to see if someone has an idea how to run a command programmatically. – Ivan Vučica Jan 27 '12 at 14:34