我想知道是否有任何方法可以同时调试(使用 gdb)子进程和父进程。我知道用于将进程更改为子进程的命令。但这不是我正在寻找的解决方案,因为这种方法只能控制孩子或父母。我正在寻找孩子和父母的同时执行步骤。
例如,假设孩子正在执行程序 b 中的第 a 步,而父母正在执行程序 d 中的第 c 步。
似乎有必要逐步完成父母和孩子的过程。有没有办法做到这一点,如果是这样,我该怎么做?
关于ctt的评论,用gdb做起来并不难,正如我刚刚发现的那样。我找到了这个资源,它适用于 ddd 和 gdb:
使用 gdb/ddd 调试子进程
如果您尝试使用 ddd 调试子进程,您可能已经注意到在调用 fork() 之后 ddd 会进入父进程(而不是子进程)。也可以调试子级,但需要特殊程序。由于子进程是一个单独的进程,它需要第二个调试器窗口,我们将利用 gdb 的能力“附加”到一个已经在运行的进程。
在开始之前,您必须执行以下操作:
确保您对 fork() 的调用为某个变量分配了一个值,以便您可以轻松读取它,例如
pid = fork()
.确保将 sleep() 语句作为 fork() 之后的第一行代码放置在 child 中,例如
sleep(60)
[使 sleep() 足够长,以便执行下面的步骤 4 ...]。调试完成后可以删除 sleep() 语句。[仅当您需要立即附加到子进程时才需要这样做。]使用“-g”选项集编译你的程序,例如
gcc myProg.c -o myProg -g
现在您可以开始了:
在后台启动 ddd [或 gdb] 的 2 个副本,例如[或对于 gdb,在两个单独的终端中
ddd myProg & ddd myProg &
正常启动 gdb(例如)]。gdb myProg
两个副本同时运行很重要。选择(任意)一个窗口作为“父”窗口,并在调用 fork() 之后设置断点(但不在子将执行的任何代码中……也就是说,在父代码中的某处设置断点…… . 如果你在孩子的代码中设置断点,DDD 会在孩子创建后立即杀死它!)。
将父节点运行到断点。注意fork()返回的值,即子进程ID。
在“child”窗口中,在 gdb 控制台窗口中键入“attach”,其中是子进程 ID。注意:gdb 控制台位于 ddd 窗口的底部;这是您可以直接向 gdb 键入命令的地方。
在 sleep() 语句之后在 child 中设置一个断点,然后单击“cont”(在弹出的“Command Tool”窗口中)以允许 child 继续执行到断点。
附加后,您还需要键入c
或continue
输入子 gdb。用于print pid
查看 的值pid
。
如果您有一个启动不同进程的进程,则启动子 gdb 并传入子进程的名称。前任。如果程序a
启动程序b
,您需要一个带有gdb a
(父 gdb)的终端和一个带有gdb b
(子 gdb)的终端。在这种情况下,您run
来自gdb a
终端(它不再是任意的)。
这个答案对我更有帮助,因为我使用的是旧版本的 gdb,它set detach-on-fork off
没有按我的预期工作。这样,您也不必暂停当前未调试的进程,这可能是出于某些目的而需要的。