运行RSpec测试时无法正常执行,输出进程内存映射并触发Ruby进程崩溃
RSpec 运行触发原生崩溃输出内存映射问题
问题表现
运行RSpec测试时,程序未执行正常测试逻辑,直接在控制台输出全量进程内存映射内容:
- 输出前段为已加载动态库的内存段信息,覆盖PostgreSQL客户端依赖、Kerberos认证依赖、bcrypt原生扩展、Ruby内置扩展等加载项,示例片段:
1030a8000-1030b8000 r-- /opt/homebrew/Cellar/postgresql/13.2_2/lib/libpq.5.13.dylib 1030b8000-1030ec000 r-x /opt/homebrew/Cellar/krb5/1.19.1/lib/libgssapi_krb5.2.2.dylib ...(中间覆盖全量已加载的系统库、Gem扩展、Ruby核心扩展内存映射) 10326c000-103270000 r-x /Users/marlomajor/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/arm64-darwin20/io/console.bundle - 输出末尾为系统崩溃提示,引导用户提交附带诊断报告的bug反馈,片段:
fc0000000-1000000000 --- 1000000000-7000000000 --- [IMPORTANT] Don't forget to include the Crash Report log file under DiagnosticReports directory in bug reports.
已尝试的修复操作
- 重新安装Ruby、Rails、PostgreSQL、rubyset环境
- 升级Homebrew全量组件
- 升级Spring预加载组件
- 升级项目全量Gem依赖
以上操作执行后,问题未得到解决
系统崩溃日志核心特征
macOS自动生成的原生崩溃诊断报告关键信息:
- 崩溃进程为ARM64原生架构的Ruby进程,运行环境为macOS 11.2,系统完整性保护处于开启状态
- 崩溃位置为主队列下的主线程,触发异常类型为
EXC_BAD_ACCESS (SIGABRT),错误原因为内核访问无效空地址0x0000000000000000,最终触发进程主动abort退出 - 日志标记崩溃类型为
EXC_CORPSE_NOTIFY,属于原生代码层面的内存访问异常,并非Ruby层的逻辑报错
针对性排查方案
结合当前Apple Silicon arm64运行环境的特征,可按以下顺序定位解决:
- 强制重编译所有带原生扩展的Gem:执行
gem pristine --all,彻底清除混装的x86_64架构动态库,避免通过Rosetta转译加载的依赖与原生arm64 Ruby进程发生内存冲突 - 排查Kerberos认证依赖冲突:从内存映射可见已加载Homebrew安装的krb5系列动态库,可将PostgreSQL连接的认证配置切换为scram-sha-256,禁用GSSAPI/Kerberos认证链路,排除认证流程中的空指针访问问题
- 清除Spring预加载缓存:删除项目
tmp/spring目录下的全部文件,杀掉后台运行的Spring进程,避免预加载的损坏内存段触发崩溃 - 临时禁用objspace扩展:运行RSpec时添加环境变量
RUBY_DISABLE_OPTIONS=objspace,排除对象空间跟踪功能导致的内存越界问题
内容的提问来源于stack exchange,提问作者Marlo
相关产品推荐
相关产品推荐

