
核心转储流行病学:修复一个18岁的老bug

OpenAI 的 Rockset 团队遇到了一个看似不可能的内存崩溃 bug:C++ 函数正常执行完毕,却在返回时跳转到空地址或栈指针错位。这是那种会让资深工程师失眠的问题——所有常规的调试手段都无效,连 ChatGPT 也猜不出原因。因为每个崩溃的栈痕迹都像被洗过牌一样,看起来毫无规律。
团队最终意识到他们不是在给一个病人看病,而是在做流行病学调查。他们停止了逐一检查核心转储的“医生模式”,转而用脚本自动化分析了过去一年所有的崩溃文件。这个种群级别的数据清洗揭示了真相:他们面对的压根不是同一个病。一批崩溃全部来自 Azure 上一个物理服务器上的不同虚拟机,是CPU 硬件悄然出错导致算错了数学。另一批则指向一个更隐蔽的根源——被他们称为18 岁老旧 bug 的 GNU libunwind 竞争条件——在异常展开过程中,信号处理函数恰好在一个指令的间隙覆盖了栈上的关键寄存器恢复数据。
最深的洞察是:一个著名的老 bug 之所以现在才暴露,是因为 Rockset 结合了高频的异常抛出、频繁的 CPU 计时器信号,以及近期对信号处理函数栈用量的修改,这三者乘积刚好越过了触发阈值。这告诉我们,很多所谓的“不可能 bug”其实不是不存在,而是你的观测条件不够极端。团队将 GNU libunwind 替换为 libgcc 的展开器并提交了上游修复,但技术修复之外,真正的价值在于证明了构建高质量的全量数据集的优先级远高于单点深度诊断——当数据清晰时,那些看似随机的事件会自动呈现出分群结构。


