问题
I've been using gdb normally for 1 or 2 projects. I.e. I invoke gdb --args prog args
. gdb runs in the same tty as the program I'm debugging.
However my latest project is modifying the dtach utility. This is a program like screen, so the tty's are redirected elsewhere, thus I have to use gdb's attach functionality.
The problem with gdb attach is that obviously you can't attach from the very beginning as you need to run the program first in order to get a pid to attach to.
Is there any way I can get a program to wait at a point until gdb is attached?
I can't use gdbserver as I'm on cygwin. Also I tried using pause()
, but that just hung when I tried to continue.
回答1:
Here is how I solve this problem. I have seen other people do this trick as well.
Pick some place you want your program to stop and wait for you to attach the debugger. For most programs, this will be the very beginning, but if there is some init work you need to do you might want to finish that up and then do this.
Put in a loop similar to this:
#ifdef DEBUG
int i = 0;
while (i == 0)
{
usleep(100000); // sleep for 0.1 seconds
}
#endif // DEBUG
Once you have successfully attached to the process, you can use the debugger to change the value of the variable i
, which will break the loop and allow normal execution to continue.
The gdb command to change the variable to 1: set var i = 1
Another thing I do all the time: I define a short function called nop()
that does nothing ("no operation"). Then I stick in a call to nop()
anyplace I want to break, and put a breakpoint inside nop()
.
Note: if you build your debug builds with -O0
then the compiler won't optimize away the variable. If you needed this trick to work with an optimized build, I guess you would need to declare the variable as volatile
.
回答2:
At least with LLDB making the process send SIGSTOP
to itself should do the trick. Debugger continue command will then issue the SIGCONT
. This should work with GDB too. Alternatively try SIGINT
instead of SIGSTOP
.
Include header
#include <signal.h>
#include <csignal> // or C++ style alternative
then
raise(SIGSTOP)
回答3:
Some platforms may have wait-for-debugger instructions or traps.
More portably, you could make the program wait on some externally satisfied condition, such as a connection to a socket or writing some data into a fifo. You could then make the connection or send dummy data from a third terminal.
Or you could put an infinite loop in the program, testing the value of some volatile variable which you would modify with the debugger in order to allow it to continue.
If I recall you can use windows apis in cygwin programs, and some web searching seems to indicate one for detecting if the program is being debugged, so you might be able to loop until that returns to.
来源:https://stackoverflow.com/questions/11255064/wait-for-gdb-to-attach