在fork之后调试子进程(配置了follow-fork-mode child)

48
我正在开发一个应用程序,其中父进程分叉出一个子进程来处理某些任务。 我遇到了一个问题,即我已经将gdb配置为follow-fork-mode child,但在分叉之后,在达到断点后,它发送了一个SIGTRAP,但子进程以某种方式终止并向父进程发送了SIGCHLD。
我在fork之前配置了signal(SIGTRAP, SIG_IGN),因此我的理解是当达到断点时,子进程应该继承并忽略SIGTRAP,但实际上并没有发生这种情况。
如果我理解有误,请帮助我理解这个问题。
如何成功调试子进程?

2
... 到达断点后,它发送 SIGTRAP ... 这是调试器被通知有断点的方式。*... 子进程以某种方式终止 ...* 正常或异常终止?您可以在父进程中使用 wait[...]([...,]&status[, ...]) 返回值上使用 WIFEXITED(status) 进行检查。有关详情,请参阅 man 3 wait - alk
1个回答

107

子进程继承父进程的信号处理程序,但不继承待处理的信号。

在fork后尝试安装 SIGTRAP 的信号处理程序,在子进程fork之后执行的代码中放置。如果您没有处理 SIGTRAP,则默认操作是终止子进程。

如果要调试子进程,必须使用 follow-fork-mode。 您必须使用该模式设置。

set follow-fork-mode child

然而,现在只能调试子进程,父进程无法检查。

另一种方法可以调试子进程。

fork()执行后,在子进程执行代码处放置一个sleep()调用,使用ps实用程序获取子进程的PID,然后附加PID。

attach <PID of child process>

现在,您可以像调试其他进程一样调试子进程。
调试完成后,您可以使用“detach PID”分离PID。
detach

执行fork()后,在子进程执行的代码中放置一个sleep()调用,使用ps实用程序获取子进程的PID,然后附加到该PID。 - 附加到子进程会再次导致sleep()执行吗?如果我错了,请纠正我。 - Yug Singh
@YugSingh 不是的,你需要在子代码中使用类似这样的结构放置sleep(): switch (fork()) { case -1: /*分支错误代码*/ case 0: sleep(30); /*剩余的子代码*/ default: /*这是父代码*/ } - jyz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接