我正在调试一个程序,该程序重复fork()
使用子进程执行某些委托任务的典型过程,因为父进程调用waitpid()
等待子进程完成,然后继续。例如:
while (!finished) {\n pid_t p = fork();\n if (p < 0) {\n perror("fork");\n exit(EXIT_FAILURE);\n }\n else if (p == 0) {\n /* Do something. For example: */\n if (/* some (rare) condition */) \n raise(SIGSEGV);\n exit(EXIT_SUCCESS);\n }\n else {\n int status;\n pid_t w = waitpid(p, &status, 0);\n if (w < 0) {\n perror("waitpid");\n exit(EXIT_FAILURE);\n }\n /* Do something. */\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n我想在 GDB 中运行该程序并调试接收信号的子进程,无论有多少其他子进程在它之前成功完成并消失。
\n\n当然,我需要set follow-fork-mode child
,因为否则 GDB 将不会查看子进程。但仅此一项就会分离父级,将 GDB 引导到第一个子级,并在其退出时完成调试。
因此,我也需要set detach-on-fork off
防止父母脱离。然而,当第一个子进程退出时,这会导致 GDB 停止并给我一个提示,父进程被挂起。我可以用来inferior
选择父母和问题continue
,但我需要为每个孩子这样做。如果第 1000 个孩子是接收到信号并且我想要查看的孩子,我需要重复此过程 999 次。
所以我想知道是否有一种方法可以自动执行此操作并让 GDB 遵循 CPU 将执行的操作,例如parent \xe2\x86\x92 child1 \xe2\x86\x92 Parent \xe2\x86 \x92 child2 \xe2\x86\x92 \xe2\x80\xa6 ,不停止并提示我,并停止在第一个接收到信号的 childN 处。
\n如果您想要调试的信号是SIGSEGV
(或导致程序核心转储的其他信号之一),最简单的解决方案可能是让子进程转储核心,然后进行事后调试。
否则,您可能想要捕获信号,打印一条消息child 23435 caught signal 2; execute gdb /proc/23435 23435
,然后使用例如挂起子进程
while(1) sleep(1);
Run Code Online (Sandbox Code Playgroud)