能否让GDB既触发自定义信号处理函数又在抛信号代码处中断?
问题:GDB调试时自定义信号处理函数不触发的解决方法
我有一个Linux C/C++应用程序,里面实现了自定义信号处理函数,用来在程序触发信号时发送邮件。正常运行时这个处理函数能被正常调用,但用GDB调试时,信号会被GDB拦截,导致我的处理函数不执行。我想同时实现两个需求:既能通过GDB查看代码崩溃位置、交互式调用栈,又能触发自定义处理函数发送邮件。
我尝试过以下代码,但在GDB中运行时处理函数不会被调用:
#include <signal.h> #include <unistd.h> struct sigaction oldSA; void handler(int signal) { const char msg[] = "Caught, should dump core now\n"; write(STDERR_FILENO, msg, sizeof msg - 1); sigaction(SIGSEGV, &oldSA, NULL); } int main() { struct sigaction sa={0}; sa.sa_handler=handler; sigaction(SIGSEGV, &sa, &oldSA); int* volatile p=NULL; *p=5; // 触发段错误 }
解决方案
配置GDB传递信号给程序
在GDB中执行命令:handle SIGSEGV pass noprint nostop
这个命令的作用是:让GDB将SIGSEGV信号传递给程序执行自定义处理(pass),不打印默认的信号提示信息(noprint),不直接暂停程序(nostop)。这样你的自定义处理函数会先执行,当处理函数恢复默认信号处理逻辑后,GDB会再次捕获到信号,此时就能查看崩溃位置和调用栈了。调试步骤示例
- 启动GDB并加载程序:
gdb ./your_program - 设置信号规则:输入
handle SIGSEGV pass noprint nostop并回车 - 运行程序:
run - 自定义处理函数执行完成后,程序会触发默认的段错误处理,GDB会自动暂停,此时可以用
bt命令查看调用栈,info registers查看寄存器状态等。
- 启动GDB并加载程序:
永久配置GDB
如果不想每次启动GDB都重复输入命令,可以把handle SIGSEGV pass noprint nostop添加到用户目录下的.gdbinit文件中,GDB启动时会自动加载该配置。
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

