14

我一直在将 gdb 用于 1 或 2 个项目。即我调用gdb --args prog args. gdb 与我正在调试的程序在同一个 tty 中运行。

但是我最新的项目是修改 dtach 实用程序。这是一个类似于屏幕的程序,因此 tty 被重定向到其他地方,因此我必须使用 gdb 的附加功能。

gdb attach 的问题在于,显然您不能从一开始就附加,因为您需要先运行程序才能获得要附加的 pid。

有什么办法可以让程序在某个时间点等待 gdb 附加?

我不能使用 gdbserver,因为我在 cygwin 上。我也尝试过使用pause(),但是当我尝试继续时它就挂了。

4

3 回答 3

18

至少使用 LLDB 将进程发送SIGSTOP给自己应该可以解决问题。然后调试器继续命令将发出SIGCONT. 这也应该适用于 GDB。或者尝试SIGINT代替SIGSTOP.

包括标题

#include <signal.h>
#include <csignal> // or C++ style alternative

然后

raise(SIGSTOP)
于 2015-06-01T16:00:23.787 回答
15

这是我解决这个问题的方法。我也看到其他人也这样做过。

选择一个您希望程序停止的地方并等待您附加调试器。对于大多数程序来说,这只是一个开始,但如果有一些初始化工作需要您完成,您可能希望完成它然后执行此操作。

放入类似这样的循环:

#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.

于 2012-06-29T03:05:22.157 回答
1

某些平台可能有等待调试器指令或陷阱。

更便携,您可以让程序等待一些外部满足的条件,例如连接到套接字或将一些数据写入fifo。然后,您可以建立连接或从第三个终端发送虚拟数据。

或者您可以在程序中放置一个无限循环,测试您将使用调试器修改的某个 volatile 变量的值,以使其继续运行。

如果我记得你可以在cygwin程序中使用windows apis,并且一些网络搜索似乎表明一个用于检测程序是否正在调试,所以你可以循环直到返回。

于 2012-06-29T02:55:09.833 回答