调试特定的子流程
Debugging a specific subprocess
我有一个 Python 脚本,它启动多个外部程序作为子进程并使用管道与它们通信。系统在 Linux 上运行。我想调试一个children,一个特定的可执行程序。我如何将 gdb 附加到它?我尝试了几种方法,但 none 有效。
- 运行 python 在 gdb 下
set follow-fork-mode child
。不起作用,因为这不是唯一的 child。第一个 child 被调试,而不是我想要的那个。
- 运行 python 在 gdb 下
set detach-on-fork off
。不可行,因为这不是唯一的child。我需要手动告诉 gdb 继续调试 parent 进程,直到启动感兴趣的程序。理论上可行,但 error-prone 手动工作太多。如果所有这些手动工作都可以自动化,这是一个可行的方法。
- 用在 gdb 下运行原始可执行文件的脚本替换有问题的可执行文件。不工作,因为管道。 gdb 的输入 and/or 输出被重定向到管道。显然我需要他们去航站楼。
我怎样才能做到这一点?
How can I accomplish this?
您可以使用 gdb -p $pid
附加一个进程而无需从 GDB 启动它。您可能需要禁用 YAMA 才能正常工作。
如果您的进程在您有机会附加它之前崩溃,this answer 展示了一种调试此类进程的方法。
更新:
Unfortunately inserting bits of code and rebuilding the program changes the behaviour.
在那种情况下,mv $exe $exe.real
,并在其位置放置一个包装器可执行文件。包装应该是这样的:
#include <unistd.h>
int main(int argc, char *argv[])
{
char argv0[PATH_MAX];
volatile int spin = 1;
strcpy(argv0, argv[0]);
strcat(argv0, ".real");
while (spin) sleep(1);
execvp(argv0, argv); // Should not return
abort(); // Unreachable
}
将GDB附加到包装器,设置spin = 0
并继续调试$exe.real
。
我有一个 Python 脚本,它启动多个外部程序作为子进程并使用管道与它们通信。系统在 Linux 上运行。我想调试一个children,一个特定的可执行程序。我如何将 gdb 附加到它?我尝试了几种方法,但 none 有效。
- 运行 python 在 gdb 下
set follow-fork-mode child
。不起作用,因为这不是唯一的 child。第一个 child 被调试,而不是我想要的那个。 - 运行 python 在 gdb 下
set detach-on-fork off
。不可行,因为这不是唯一的child。我需要手动告诉 gdb 继续调试 parent 进程,直到启动感兴趣的程序。理论上可行,但 error-prone 手动工作太多。如果所有这些手动工作都可以自动化,这是一个可行的方法。 - 用在 gdb 下运行原始可执行文件的脚本替换有问题的可执行文件。不工作,因为管道。 gdb 的输入 and/or 输出被重定向到管道。显然我需要他们去航站楼。
我怎样才能做到这一点?
How can I accomplish this?
您可以使用 gdb -p $pid
附加一个进程而无需从 GDB 启动它。您可能需要禁用 YAMA 才能正常工作。
如果您的进程在您有机会附加它之前崩溃,this answer 展示了一种调试此类进程的方法。
更新:
Unfortunately inserting bits of code and rebuilding the program changes the behaviour.
在那种情况下,mv $exe $exe.real
,并在其位置放置一个包装器可执行文件。包装应该是这样的:
#include <unistd.h>
int main(int argc, char *argv[])
{
char argv0[PATH_MAX];
volatile int spin = 1;
strcpy(argv0, argv[0]);
strcat(argv0, ".real");
while (spin) sleep(1);
execvp(argv0, argv); // Should not return
abort(); // Unreachable
}
将GDB附加到包装器,设置spin = 0
并继续调试$exe.real
。