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

macOS访问受保护内存出现异常总线错误问题求助

嘿,这个问题我之前在调试跨平台程序时也碰到过!让我给你理清楚背后的原因,以及怎么调整你的程序适配macOS。

为什么macOS抛出Bus Error而不是SIGSEGV?

首先得明确这两个信号的核心差异:

  • SIGSEGV(段错误):一般是访问了属于进程地址空间,但没有操作权限的内存(比如写只读区域),或者访问了地址空间内“理论上可扩展”的不存在区域(比如栈溢出时内核可以动态映射)。
  • Bus Error(对应信号SIGBUS):是访问了完全不属于进程地址空间的物理地址,或者硬件层面无法完成的内存操作(比如某些严格的内存对齐错误)。

Linux和macOS的内存管理内核逻辑有差异,尤其是老版本的macOS(比如你的10.11.6),对于空指针访问、未映射地址访问这类操作,内核会判定为硬件层面无法完成的请求,因此抛出SIGBUS;而Linux则会把这类情况归类为段错误,抛出SIGSEGV。

怎么让程序在macOS上也能捕获到预期的信号?

最简单的解决办法就是同时注册SIGSEGV和SIGBUS的信号处理器,这样不管系统抛出哪个信号,你的程序都能捕获并处理。

给你个示例代码参考:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void signal_handler(int sig) {
    if (sig == SIGSEGV) {
        printf("捕获到SIGSEGV信号!\n");
    } else if (sig == SIGBUS) {
        printf("捕获到Bus Error(SIGBUS)信号!\n");
    }
    exit(EXIT_FAILURE);
}

int main() {
    // 同时监听两个信号
    signal(SIGSEGV, signal_handler);
    signal(SIGBUS, signal_handler);
    
    // 触发非法内存访问(Linux下SIGSEGV,macOS下SIGBUS)
    int *null_ptr = NULL;
    *null_ptr = 42;
    
    return 0;
}
如果你想专门触发SIGSEGV测试

如果你的目的是刻意生成SIGSEGV,可以试试修改只读内存的操作,这种场景下macOS和Linux都会抛出SIGSEGV:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void sigsegv_handler(int sig) {
    printf("成功捕获SIGSEGV!\n");
    exit(EXIT_FAILURE);
}

int main() {
    signal(SIGSEGV, sigsegv_handler);
    
    // 指向只读数据段的字符串
    char *read_only_str = "这是只读字符串";
    *read_only_str = 'X'; // 修改只读内存,触发SIGSEGV
    
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:25:27