I have a process that is called by another process which is called by another process and so on ad nauseum. It\'s a child process in a long tool chain.
This process
On Mac OS X, you can use:
(gdb) attach --waitfor <process-name>
but this also is sometimes unable to capture processes that exit very quickly. I'm unsure if this is supported on any other platforms.
GDB Release Notes for Mac OS X v10.5 WWDC Seed
I've been facing a similar problem with something I'm trying to debug, and I came up with a solution using ldpreload, but after seeing Joeys answer I think I'll try that first. In case it's helpful to anyone else though here's the idea:
Create an LD_PRELOAD library to hook the exec* calls (there's plenty of guides on how to do this around, but if I do this I'll update my answer with the code), check the path used when passing through the exec* call, if it's our target then output a message with the PID to stderr and go into an infinite loop (with sleep to avoid massive CPU usage). Then you can attach with gdb and modify the register used in the loop to continue execution.
This may involve some inline ASM to make sure the compiler doesn't optimise the infinite loop in such a way that makes it hard to break out of. A more eloquent way of doing it would be to find a way to detect that gdb has attached then trigger a breakpoint ("asm("int3");" should do the trick on the latter).
Here is my script called gdbwait:
#!/bin/sh
progstr=$1
progpid=`pgrep -o $progstr`
while [ "$progpid" = "" ]; do
progpid=`pgrep -o $progstr`
done
gdb -ex continue -p $progpid
Usage:
gdbwait my_program
Sure it can be written nicer but Bourne shell script syntax is painful for me so if it works then I leave it alone. :) If the new process launches and dies too quick, add 1 second delay in your own program for debugging ...
Not exactly what you expect, but it might help you in debugging.
valgrind --trace-children=yes your_program
will check and print memory errors in all children of the process, with stack trace and some detail about the error (eg. in case of double-free, you'd get the stack trace of the first free).
Also, you might make the crashing process generate a core dump, and debug this post-mortem. See this answer for details.
You can attach to a parent process and set follow-fork-mode child. This will make gdb debug child process instead of parent after forking. Also catch fork will be useful. This will make gdb stop after each fork. See docs.
One of the programs in Tom Tromey's gdb-helpers repository on GitHub is preattach
, which will make gdb attach to the next process created with a given name. It requires the Linux systemtap program.