MacOS下调用glfwCreateWindowSurface触发EXC_BAD_ACCESS崩溃
崩溃点位于glfwCreateWindowSurface调用时初始化CAMetalLayer的流程中,错误码EXC_BAD_ACCESS(code=1, address=0x260000000020)是MacOS下GLFW编译配置错误、Vulkan Portability适配缺失导致的典型问题,按以下优先级排查修复:
1. 修正GLFW编译配置(触发概率90%以上)
使用源码编译引入GLFW 3.3-stable版本时,该版本的Cocoa平台后端代码基于手动引用计数(MRC)实现。如果编译GLFW源文件时全局开启了Objective-C自动引用计数(ARC,即添加了-fobjc-arc编译标记),会直接和GLFW自身的内存管理逻辑冲突,在创建Metal渲染层时触发objc_retain流程崩溃。
- 修复操作:对GLFW的所有编译单元单独添加
-fno-objc-arc编译选项,仅对自有业务代码保留ARC配置即可。 - 编译检查:确保GLFW编译链接时正确关联MacOS原生依赖框架:
Cocoa、Foundation、QuartzCore、IOKit。依赖框架缺失不会触发编译报错,会直接导致运行时内存异常。
2. 补全Vulkan实例启用扩展
当前代码仅在MacOS平台添加了VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR实例创建标记,未同步启用对应的Portability扩展,会导致MoltenVK运行时出现未定义行为:
修改getRequiredExtensions逻辑,MacOS平台下额外加入两个必填扩展:
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
注意:直接使用Vulkan头文件中定义的宏,不要硬编码扩展名字符串,避免拼写错误。
3. 升级GLFW版本(上述操作无效时执行)
GLFW 3.3-stable分支对Vulkan 1.3版本、MacOS 12及以上系统的Metal表面创建逻辑存在已知兼容bug,将GLFW子模块切换到3.4稳定分支即可修复:
cd ThirdParty/glfw git fetch origin 3.4-stable git checkout 3.4-stable
切换后重新编译整个项目即可。
前置校验项
修复完成后确认以下条件满足,不需要额外调整代码逻辑:
- 所有GLFW、Vulkan接口调用均在主线程执行(当前崩溃栈显示调用在主线程,符合要求)
glfwInit返回值为GLFW_TRUE,glfwCreateWindow返回的窗口句柄非空glfwGetRequiredInstanceExtensions返回的所有扩展都已加入Vulkan实例的启用扩展列表,不要手动过滤GLFW要求的必填扩展
内容的提问来源于stack exchange,提问作者Tac Uchiha

