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

macOS崩溃日志中EXC_BAD_ACCESS (SIGILL)是什么?Unity程序崩溃排查

Unity程序崩溃:EXC_BAD_ACCESS (SIGILL) 原因排查指南

首先明确:EXC_BAD_ACCESS (SIGILL) 不是单纯的内存访问错误,SIGILL代表CPU尝试执行非法指令,常见于iOS/macOS平台,下面是具体的排查方向:

  • 原生插件架构或接口不匹配
    这是最常见的原因:

    • 插件编译的CPU架构和目标设备不兼容,比如用x86_64编译的插件部署到arm64设备上,会直接触发非法指令。可以用lipo -info [插件路径]查看插件支持的架构,确保和Unity PlayerSettings里勾选的一致。
    • C#调用插件时参数、返回值类型不匹配,比如把C#的int传给插件的float参数,或者插件返回的指针被C#错误转换,都会导致执行非法指令。务必逐行核对插件的C#绑定代码和原生代码的接口定义。
  • IL2CPP编译优化问题
    开启Release模式的IL2CPP高优化时,编译器可能生成有问题的机器码,尤其是涉及:

    • unsafe代码块的指针操作
    • 复杂泛型类型的内存布局
    • 结构体的强制类型转换
      排查时可以临时把PlayerSettings里的Optimization Level设为None,如果崩溃消失,说明是优化导致。找到对应的代码块,要么调整写法避免歧义,要么给该代码所在的类/方法加[Il2CppSetOption(Option.Optimization, 0)]属性单独禁用优化。
  • 内存越界破坏代码段
    虽然报错是SIGILL,但内存越界操作(比如数组越界写入、指针错误寻址)可能覆盖了程序代码段的内存,导致CPU执行被篡改后的非法指令。
    排查时可以:

    • 启用Unity Memory Profiler,追踪异常的内存分配和写入操作
    • 在Xcode中开启Address Sanitizer(Product -> Scheme -> Edit Scheme -> Diagnostics -> Address Sanitizer),运行程序时会自动检测内存越界并定位到代码行。
  • 硬件指令集不兼容
    如果代码或插件使用了目标设备不支持的CPU指令集扩展,比如在armv7设备上使用arm64专属指令,或者在老款Intel CPU上使用AVX指令,会触发SIGILL。
    检查PlayerSettings里的CPU Architecture选项,只勾选目标设备支持的架构;如果是原生插件,确认编译时没有启用超出目标设备能力的指令集(比如Xcode里的Build Settings -> Other C Flags不要加-mavx这类选项)。

  • 托管对象被GC回收导致的原生代码错误
    当C#把托管对象的指针传给原生代码后,如果该对象被GC回收,原生代码再访问这块内存时,内存可能已经被重新分配为其他数据(甚至是代码),进而触发非法指令。
    解决方法是用GCHandle.Alloc(对象, GCHandleType.Pinned)固定托管对象,确保在原生代码使用期间不会被GC回收,用完后调用GCHandle.Free()释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:47:20