OpenAI Fixes 18-Year-Old GNU libunwind Bug by Treating Crash Debugging Like Epidemiology

TL;DR · AI 摘要
OpenAI Fixes 18-Year-Old GNU libunwind Bug by Treating Crash Debugging Like Epidemiology - InfoQ InfoQ Homepage News Ope...
核心要点
- 主题聚焦:OpenAI Fixes 18-Year-Old GNU libunwind Bug by Tr
- 来源:InfoQ,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
OpenAI通过将崩溃调试视为流行病学修复了存在18年的GNU libunwind漏洞 - InfoQ
InfoQ 首页 新闻 OpenAI通过将崩溃调试视为流行病学修复了存在18年的GNU libunwind漏洞
开发
在线 InfoQ AI 安全与隐私工程认证(8月26日):在受监管环境中部署AI?
OpenAI通过将崩溃调试视为流行病学修复了存在18年的GNU libunwind漏洞
2026年7月9日 3分钟阅读
作者:
- Steef-Jan Wiggers
#### 关注我们
YouTube
232K关注者
26K关注者
新
RSS
19K读者
X
57.1k关注者
21K点赞
Bluesky
收听本文 -
0:00
音频准备就绪
您的浏览器不支持音频元素。
正常
1.25x
1.5x
喜欢
新下拉阅读列表
- 阅读列表
OpenAI工程师花费数周时间试图解释Rockset中出现的神秘崩溃,Rockset是支持ChatGPT搜索和数据插件的C++数据基础设施服务。函数似乎返回到虚假的内存地址,堆栈指针在执行过程中似乎会突然偏移8字节。团队构建的每个假设都面临强有力的证据反对,这个漏洞看起来似乎不可能存在。
他们最初假设的单个漏洞实际上是由两个互不相关的漏洞巧合地同时被发现。突破性进展并非来自对单个崩溃的深入检查,而是团队转向了他们称之为“流行病学调试”的方法:构建一个自动分析过去一年所有生产环境核心转储的流水线,然后寻找群体层面的模式,而不是针对个别案例进行推理。
团队让ChatGPT编写了一个脚本,下载每个核心文件的前缀,提取寄存器,过滤已知的误报,并将每个崩溃标记为“返回空指针”、“堆栈对齐错误”或其他类型。他们并行处理了过去一年所有Rockset核心转储文件。相关性立即显现出来。原本看似单一的综合征实际上是由两个具有完全不同特征的崩溃群体组成的。
所有“堆栈对齐错误”崩溃都来自Azure的一个特定区域,有明确的起始日期,且从未出现在长期运行的节点上。团队追踪到这些崩溃源自单个物理主机,该主机的CPU在静默状态下产生错误结果。并非过热,也未触发机器检查异常,只是在进行数学运算时悄然出错。一旦将该主机从服务中移除,“堆栈对齐错误”崩溃立即完全消失。
在隔离出硬件相关崩溃后,剩余的“返回空指针”崩溃变得可追踪。团队此前曾排除C++异常展开作为原因,因为他们认为有反例:在不使用异常的代码路径中出现的崩溃。但这些反例都来自硬件损坏集群。一旦消除这种污染,所有剩余的崩溃都发生在异常展开过程中。
根本原因是在 GNU libunwind 的 _Ux86_64_setcontext 函数中存在一个持续了 18 年的竞态条件。在 C++ 异常展开过程中,libunwind 会在栈上合成一个 ucontext_t 结构体,填充目标寄存器状态,然后调用 _Ux86_64_setcontext 将控制权转移到清理处理程序。问题在于:_Ux86_64_setcontext 在完成从旧结构体中读取指令指针之前,就先将栈指针(%rsp)更新为指向新的栈帧。一旦 %rsp 发生变化,该结构体就不再属于活动栈,也不再受到内核 red zone 保证的保护。如果信号恰好在 %rsp 更新和 %rip 读取之间的瞬间到达,内核会在该结构体上构建信号帧,导致指令指针被破坏。函数随后会跳转到 NULL 或垃圾数据地址。
该竞态窗口恰好只有一条指令宽。在现代时钟频率下,这大约是 100 皮秒。在大多数程序中,这种情况几乎不会触发。OpenAI 的 Rockset 使用 timer_create 每隔几毫秒的 CPU 时间就发送一个 SIGUSR2 信号,用于轻量级的每查询会计,这产生了远多于典型应用的信号传递事件。这种频率将理论上可能的竞态条件转化为实际的生产环境崩溃。
团队已将修复方案和自包含的复现程序提交给 GNU libunwind,并验证其他展开器(如 libgcc)不存在相同问题。该修复通过调整指令顺序,使 %rip 的读取发生在 %rsp 更新之前,彻底消除了竞态窗口。
团队对教训的总结值得全文引用:
最重要的步骤不是巧妙的汇编代码阅读或对细节的深入理解,而是构建了一个高质量的数据集。在缺乏该数据集的情况下,我们曾将两种不同的现象混为一谈,并试图通过推理摆脱困惑。一旦我们获得了准确完整的统计数据,问题的结构就变得显而易见。
对于任何正在调试难以解释的生产环境崩溃的团队:请检查是否混淆了多个错误。看似与所有假设都不一致的症状,实际上可能完全一致——它们可能与两个不同的假设相吻合,而你可能无意中将它们混在一起了。快速看清问题结构的路径不是对单个案例的深入分析,而是对所有失败案例的完整、标注数据的全局视图。
完整的工程博客文章包含详细的堆栈图示、易受攻击的汇编指令,以及揭示两个群体的崩溃率可视化图表。
关于作者
Steef-Jan Wiggers
显示更多
显示更少
#### 本文属于“缺陷与热修复”主题
##### 相关主题:
- 开发
- AI、机器学习与数据工程
- 缺陷与热修复
- 开源项目发布
- OpenAI
- 站点可靠性工程
- 相关编辑内容
- 相关赞助商 警报疲劳正在让你付出代价:生产可靠性与 AI 采用现状
- 相关赞助商 在完全配置的环境中探索 NeuBird AI 玩具场,连接到实时 AWS 运行时数据。尝试你的第一个查询!
InfoQ 新闻通讯
每周五内容精选,每周二发送。加入超过 25 万名高级开发者的社区。查看示例
我们保护您的隐私。