我一直在为1或2个项目使用gdb。即我调用了gdb --args prog args
。 gdb与我正在调试的程序运行在相同的tty中。
但是我的最新项目是修改dtach实用程序。这是一个类似于屏幕的程序,因此tty被重定向到其他地方,因此我必须使用gdb的附加功能。
gdb attach的问题是,显然你不能从一开始就附加,因为你需要先运行程序才能得到一个pid来连接。
有什么方法可以让程序等到某个点,直到连接gdb?
我不能使用gdbserver,因为我在cygwin上。我也尝试使用pause()
,但是当我试图继续时它就挂了。
答案 0 :(得分:13)
以下是我如何解决这个问题。我也看到其他人也这样做了。
选择您希望程序停止的某个位置并等待您附加调试程序。对于大多数程序来说,这将是一个开始,但如果你需要做一些初始化工作,你可能想要完成它然后这样做。
放入类似于此的循环:
#ifdef DEBUG
int i = 0;
while (i == 0)
{
usleep(100000); // sleep for 0.1 seconds
}
#endif // DEBUG
成功连接到进程后,可以使用调试器更改变量i
的值,这将打破循环并允许正常执行继续。
将变量更改为1的gdb命令:set var i = 1
我一直在做的另一件事:我定义了一个名为nop()
的简短函数,它什么都不做(“无操作”)。然后我坚持打电话给nop()
我要打破的任何地方,并在nop()
内放一个断点。
注意:如果使用-O0
构建调试版本,则编译器不会优化掉变量。如果你需要这个技巧来使用优化的构建,我想你需要将变量声明为volatile
。
答案 1 :(得分:10)
至少LLDB让流程发送SIGSTOP
给自己应该可以解决问题。然后,调试器继续命令将发出SIGCONT
。这也适用于GDB。或者,尝试使用SIGINT
代替SIGSTOP
。
包含标题
#include <signal.h>
#include <csignal> // or C++ style alternative
然后
raise(SIGSTOP)
答案 2 :(得分:1)
某些平台可能有等待调试器指令或陷阱。
更方便的是,您可以让程序等待一些外部满足的条件,例如连接到套接字或将一些数据写入fifo。然后,您可以建立连接或从第三个终端发送虚拟数据。
或者您可以在程序中放置一个无限循环,测试一些易变量的值,您可以使用调试器修改该变量以允许它继续。
如果我记得你可以在cygwin程序中使用windows apis,并且某些网络搜索似乎表明用于检测程序是否正在被调试,那么你可以循环直到返回。