OpenAI 開發團隊透過流行病學分析法,成功定位並修復了導致資料基礎設施崩潰的兩項關鍵錯誤。
核心除錯策略
OpenAI 團隊在面對 ChatGPT 資料基礎設施(特別是 Rockset 服務)中難以解釋的崩潰現象時,改變了傳統逐一檢查 core dump 的「醫生模式」,轉而採用「流行病學模式」。他們利用 ChatGPT 編寫腳本,對過去一年內所有的崩潰資料進行自動化標記與分類,從而發現這些崩潰並非單一原因,而是由兩起互不相關的錯誤共同導致。
兩項關鍵錯誤分析
硬體故障:透過分析發現,部分崩潰集中在特定區域與時間點,追溯後確認是由單一 Azure 實體主機的 CPU 硬體錯誤所致。團隊已將該主機列入黑名單,並更新監控機制以利未來快速偵測類似硬體異常。
開源程式庫漏洞:針對剩餘的「返回空值(return-to-null)」崩潰,團隊發現其根源在於 GNU libunwind 程式庫中存在長達 18 年的競態條件(race condition)。該程式庫在執行 C++ 例外處理(exception unwinding)時,會將暫存器狀態寫入堆疊,而在更新 %rsp 指標後、讀取返回位址前的極短時間視窗內,若收到訊號(如 SIGUSR2),核心會覆寫該記憶體區域,導致程式崩潰。
技術影響與啟示
此漏洞之所以難以察覺,是因為其觸發視窗僅約 100 皮秒(picoseconds)。然而,由於 Rockset 在處理資料攝取背壓(backpressure)時會頻繁拋出例外,導致該機率極低的競態條件在大規模運作下頻繁發生。
為何這個 18 年老漏洞現在才浮現
崩潰率大致與例外拋出頻率、訊號發送頻率及訊號處理常式的堆疊用量成正比。Rockset 在這三項指標上都異於常規:以高頻率拋出例外作為過載控制機制、因 coarsethreadcputimeclock 而異常頻繁發送 SIGUSR2 訊號,且今年稍早為統計合併訊號而在處理常式中新增 timergetoverrun 呼叫,導致其堆疊用量增加。團隊認為正是這項堆疊用量的變動成為關鍵轉折——在此之前完全未觀察到此類崩潰。三項因素的乘積在近期才跨過「可被實際觀察到」的門檻,這也解釋了為何硬體錯誤與 libunwind 錯誤兩者的崩潰都巧合地集中在同一方法 DocumentTree::updateDocument(該方法在拋出背壓例外時持續作用中,且故障硬體節點所屬機型也主要用於批次資料攝取)。
修復方案
團隊的即時緩解措施是將例外處理從 GNU libunwind 切換至 libgcc 的實作(額外好處是 libgcc 在降低鎖競爭上已有大量優化,有利於大型虛擬機的擴展性)。團隊也已將可重現的最小案例與修復方案回報並合併至 GNU libunwind 官方專案,並確認其他 unwinder 實作無類似問題。
核心教訓:群體層級診斷的力量
OpenAI 團隊總結,這次除錯過程中最關鍵的一步並非艱澀的組合語言分析或系統底層知識,而是建立一份高品質的完整資料集——在缺乏這份資料前,團隊誤將兩種截然不同的故障現象混為一談,難以理出頭緒;一旦取得完整且準確的群體資料,問題結構立刻變得清晰。這強化了團隊對深度監測工具、自動化調查與維運工具持續改善的投入方向。
原文:https://easyvibecoding.app/curated/2281