You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否让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会再次捕获到信号,此时就能查看崩溃位置和调用栈了。

  • 调试步骤示例

    1. 启动GDB并加载程序:gdb ./your_program
    2. 设置信号规则:输入handle SIGSEGV pass noprint nostop并回车
    3. 运行程序:run
    4. 自定义处理函数执行完成后,程序会触发默认的段错误处理,GDB会自动暂停,此时可以用bt命令查看调用栈,info registers查看寄存器状态等。
  • 永久配置GDB
    如果不想每次启动GDB都重复输入命令,可以把handle SIGSEGV pass noprint nostop添加到用户目录下的.gdbinit文件中,GDB启动时会自动加载该配置。

内容的提问来源于stack exchange,提问作者intrigued_66

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:51:03