GDB调试时执行popen提前退出报SIGTRAP信号错误是什么原因?
问题成因
- GDB实现单步调试的底层依赖CPU的陷阱标志位(TF),开启该标志后CPU每执行一条指令就会触发
SIGTRAP信号,由GDB接收后控制程序执行流程。 popen内部会调用fork()创建子进程执行命令,fork生成的子进程会完全继承父进程的调试状态,包括单步时开启的TF标志位。- 子进程执行
exec加载命令程序前,会调用你定位到的__libc_signal_block_all函数屏蔽所有信号,保证exec操作的原子性。此时子进程触发的SIGTRAP信号没有对应的调试器接管(GDB默认不会自动附加到fork生成的子进程),同时信号被进程自身的屏蔽规则拦截,内核无法处理该异常,直接终止进程并抛出SIGTRAP错误,最终导致整个调试会话异常终止。
解决方法
- 不要单步进入或单步跳过
popen调用,直接在popen后的代码行设置断点,执行continue命令直接运行到断点位置即可正常调试后续逻辑。 - 也可以手动调整GDB的fork跟踪规则:
- 执行
set follow-fork-mode parent明确指定GDB在fork后只跟踪父进程,自动剥离子进程的调试状态 - 若需要调试子进程逻辑,可执行
set detach-on-fork off让GDB同时接管父子进程的调试
- 执行
内容的提问来源于stack exchange,提问作者QnA
相关产品推荐
相关产品推荐

