一次 CPU Profiler 引发的 loader lock 重入死锁
太长不看版
某 C++ 服务在运行期启用 gperftools CPU profiling 后停止响应:profile 文件创建成功,但一直保持 0 字节;服务心跳不再推进,监控进程随后因心跳超时生成 core。看起来像 profiler 没写出文件,实际是服务线程已经卡死在一次采样里。
根因方向是 profiler 在信号处理函数里做了不完全信号安全的调用栈采样,和业务线程当时正在执行的异常处理路径撞到一起,最终形成同一线程重入同一把内部锁的死锁。
规避上有完全规避和部分规避两类手段。本文结论是优先评估 GCC/libgcc 运行时升级;unwind_safeness_helper 只能作为特定构建下的定制兜底,不建议当成通用推荐方案。