OpenAI 코어 덤프 역학: 18년 된 libunwind 버그 수정

OpenAI 코어 덤프 역학: 18년 된 libunwind 버그 수정

OpenAI는 Rockset 내에서 설명할 수 없는 일련의 충돌을 해결했습니다. Rockset은 ChatGPT의 데이터 플러그인과 대화 검색에 사용되는 C++ 기반 데이터 인프라 서비스입니다. 조사는 aparentemente 단일 문제로 보였던 것이 실제로는 두 개의 관련 없는 버그임을 밝혀냈습니다: 특정 Azure 호스트에서의 silenz한 하드웨어 손상과 GNU libunwind 라이브러리의 오래된 경합 조건.

인구 수준 진단 vs. 사례별 디버깅

조사의 전환점은 '의사' 접근 방식(개별 코어 덤프 분석)에서 '역학자' 접근 방식(충돌 전체 인구 분석)으로의 전환이었습니다. 자동화된 파이프라인을 구축하여 1년 분량의 프로덕션 코어 덤프를 분석함으로써, OpenAI는 레지스터 상태와 패턴을 기반으로 충돌을 distinct 클러스터로 분류할 수 있었습니다.

이 데이터 중심 접근 방식은 두 개의 별개 충돌 인구를 드러냈습니다:

  • Misaligned-stack crashes: 이들은 한 지역의 단일 물리적 호스트에 국한되었으며 명확한 시작 날짜가 있어 하드웨어 고장을 나타냈습니다.
  • Return-to-null crashes: 이들은 여러 클러스터와 지역에 퍼져 있어 소프트웨어 수준의 체계적 문제를 시사했습니다.

버그 1: silenz한 하드웨어 손상

하나의 충돌 클러스터는 CPU가 계산을 잘못 수행하고 있던 singolo 물리적 Azure 호스트로 추적되었습니다. 이로 인해 실행 중 스택 포인터(%rsp)가 잘못 정렬되어 함수 반환 시 충돌이 발생했습니다.

손상이 silenz하고 통제된 환경에서 재현할 수 없었기 때문에, OpenAI는 호스트를 deny 목록에 추가하여 문제를 완화했습니다. 향후 발생을 방지하기 위해 팀은 로그에 레지스터 상태를 포함하도록 치명적 신호 핸들러를 개선하여 전체 코어 덤프 없이도 더 빠른 감지를 가능하게 했고, 컨트롤 플레인을 업데이트하여 재사용을 재활용보다 선호하도록 하여 bad-node 감지를 쉽게 만들었습니다.

버그 2: 18년 된 GNU libunwind 경합 조건

기술적 메커니즘

GNU libunwind가 언와인드 전송을 수행할 때, 원하는 레지스터 상태를 유지하기 위해 스택에 ucontext_t 구조체를 합성합니다. 취약점은 _Ux86_64_setcontext 어셈블리 루틴에 존재합니다:

  1. 이 루틴은 스택 포인터(%rsp)를 활성 스택의 새로운 하단으로 업데이트합니다.
  2. %rsp가 업데이트된 후, ucontext_t 구조체는 활성 스택이나 커널에 의해 보호되는 128바이트 아래의 "레드 존"(%rsp 아래 128바이트)의 일부가 더 이상 아닙니다.
  3. 이 exact 순간에 신호(SIGUSR2 등)가 전달되면, 커널은 %rsp-128에 신호 프레임을 구축하여 잠재적으로 ucontext_t 메모리를 덮어쓸 수 있습니다.
  4. 손상된 메모리에서 복원된 명령어 포인터(%rip)를 읽으면 프로그램이 충돌하며—종종 NULL로 반환됩니다.

경합 창과 확률

경합 창은 약 한 명령어 너비이며, 약 100 피코초로 추정됩니다. 극도로 좁지만, Rockset 환경의 세 가지 요인으로 인해 충돌 빈도가 운영적으로 가시화되었습니다:

  • 높은 예외율: Rockset은 내부 ingest 백압력에 예외를 사용하며, 과부하된 호스트에서 초당 최대 $10^4$개의 예외를 발생시킵니다.
  • 높은 신호율: coarse_thread_cputime_clock은 CPU 시간마다 몇 밀리초 간격으로 SIGUSR2 신호를 전달합니다.
  • 증가된 스택 사용량: SIGUSR2 핸들러에 대한 최근 업데이트에서 timer_getoverrun 호출이 추가되어 핸들러가 사용하는 스택 양이 증가하고, 이로 인해 오래된 ucontext_t 메모리를 덮어쓸 가능성이 높아졌습니다.

해결 및 완화

OpenAI는 GNU libunwind에서 libgcc의 언와이너로 전환하여 libunwind 문제를 해결했으며, 이는 큰 VM에서 락 경합을 줄여 성능 향상도 제공했습니다. 또한, OpenAI는 자체 포함 재현자와 수정을 GNU libunwind 프로젝트에 업스트림하여 더 넓은 커뮤니티에 대한 버그를 해결했습니다.

Sources