I want to debug a program, using gdb. But I invoke that program through a script.
How can I use gdb?
The script is long and its not possible for me to invoke the program directly using command line arguments from gdb.
Also the process that is created when the script starts is short lived so can't attach gdb to the process.
What I want to do is something like, start gdb with that program, add my breakpoints then
execute the script (FYI - it also takes arguments), then when it hits breakpoint do whatever I want.
I looked at shell option in gdb, but that spawns a new shell if I am not wrong and return to gdb when done. This is not what I want.
Please let me know if there is a better way.
There are several ways.
The truly old-school way is to hack a loop into your program's main
like:
volatile int zzz;
...
int main() {
while (!zzz) sleep (1);
Then, run your script. In a separate window, run gdb on the program you want to debug, and use attach
to attach to the sleeping program. Then you can set breakpoints, etc, and finally:
(gdb) set var zzz = 1
(gdb) cont
A slightly newer ("new" as in "it's been in gdb at least 10 years") way is to edit your script and put a gdb --args
before the invocation of the program you want to debug. This method doesn't always work, though. It doesn't handle redirections properly, among other things.
Finally, you can use multi-inferior debugging. This is the "newest" approach of all. Here I'm following my own blog post on the topic:
$ gdb /bin/sh # or whatever runs your script
(gdb) set args arguments-to-the-script
(gdb) set detach-on-fork off
(gdb) set target-async on
(gdb) set non-stop on
(gdb) set pagination off
Then you can do something like:
(gdb) add-inferior -exec program-you-want-to-debug
... then switch to that inferior and set breakpoints. Now switch back to the first inferior and run
-- it should all work!
A couple of methods I have used in the past.
- Rename
yourprog
to yourprog.real
. Make a script named yourprog
that runs gdb --args yourprog.real "$@"
.
- Make
yourprog
invoke gdb
on its own pid
, then call sleep
in a loop.