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

段错误(SEGV)异常是否仅能触发一次?附测试验证

段错误(SEGV)异常是否仅能触发一次?

答案是:不是,但你的测试代码里因为信号处理的默认行为限制,导致第二次触发SEGV时直接终止进程,只捕获到一次。下面结合你的测试代码和现象逐一分析:

测试现象拆解

你的测试逻辑是:通过setjmp保存执行环境,触发异常后用longjmp跳回异常触发前的位置,尝试重复触发信号。结果是:

  • SEGV信号仅被捕获一次,之后进程直接终止;
  • 取消注释assert(1 == 3)后,ABRT信号会被无限捕获,进入循环。

核心原因分析

1. SEGV仅触发一次的原因

你使用的signal()函数在多数Linux系统默认的System V风格实现中,当信号处理函数被调用前,系统会自动将该信号的处理方式重置为默认(SIG_DFL)。

对应到你的代码:

  • 第一次触发SEGV(*(int *)0)时,进入自定义的handle_segment_violation函数,通过longjmp跳回主逻辑,此时i被修改为1;
  • 再次执行*(int *)1触发SEGV时,该信号的处理方式已经被重置为默认,系统直接执行默认操作——终止进程,因此不会再进入你的处理函数,只看到一次catch segv输出。

如果想要多次捕获SEGV,需要在信号处理函数中重新注册信号处理逻辑,修改后的处理函数如下:

void handle_segment_violation(int sig) {
    printf("catch segv\n");
    signal(SIGSEGV, handle_segment_violation); // 重新注册信号处理
    longjmp(g_position_env, 2);
}

2. ABRT无限循环的原因

assert(1 == 3)会调用abort()函数,abort()的特殊行为导致了无限循环:

  • abort()会向进程发送SIGABRT信号;
  • 如果你的信号处理函数通过longjmp直接跳走(而非正常返回),abort()的后续终止逻辑不会执行;
  • 程序跳回loop_abrt标签后,再次执行assert,再次触发abort()发送SIGABRT,从而形成循环。

另外,abort()本身的逻辑规定:如果信号处理函数正常返回,它会重置SIGABRT的处理方式为默认并再次发送信号,确保进程终止。但你的代码中用longjmp跳过了这个流程,所以能持续触发信号。

完整测试代码(修正SEGV多次捕获)

#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include <setjmp.h>

jmp_buf g_position_env;

void handle_abort(int sig) {
    printf("catch abort\n");
    longjmp(g_position_env, 1);
}

void handle_segment_violation(int sig) {
    printf("catch segv\n");
    signal(SIGSEGV, handle_segment_violation); // 重新注册信号处理
    longjmp(g_position_env, 2);
}

int main() {
    unsigned int i;
    int ret;
    signal(SIGABRT, handle_abort);
    signal(SIGSEGV, handle_segment_violation);
    i = 0;
    ret = setjmp(g_position_env);
    if (ret == 1) {
        goto loop_abrt;
    } else if (ret == 2) {
        i++;
        goto loop_segv;
    }    
loop_abrt:
    // uncomment code below, it will enter a loop
    //assert(1 == 3);
loop_segv: 
   printf("i = %d\n", i);
   printf("%d\n", *(int *)i);
  
    printf("-----------end\n");
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:17:08