
OpenAI 공식 엔지니어링 글에 따르면 회사는 ChatGPT 데이터 인프라에서 발생한 C++ 서비스 충돌을 대규모 코어 덤프 분석으로 추적해, 서로 다른 두 원인을 분리해냈다. 하나는 특정 Azure 물리 호스트의 하드웨어 이상이었고, 다른 하나는 GNU libunwind에 오랫동안 남아 있던 경쟁 조건이었다.
문제가 드러난 서비스는 OpenAI가 2024년 인수한 Rockset 기반 데이터 인프라와 관련돼 있다. OpenAI는 이 인프라가 ChatGPT가 답변을 생성하거나 작업을 수행할 때 관련 데이터를 검색하는 데 쓰인다고 설명했다. 일부 구성 요소는 성능과 메모리 효율을 위해 C++로 작성됐고, 드물게 정상 함수가 끝난 뒤 잘못된 주소로 복귀하는 것처럼 보이는 충돌이 발생했다.
초기 분석은 난항을 겪었다. 로그에 남은 스택 트레이스가 손상되거나 불완전했고, 몇 개의 코어 덤프만 정밀 분석하는 방식으로는 원인을 좁히기 어려웠다. OpenAI는 이후 각 코어 파일의 일부를 내려받아 레지스터 상태를 추출하고, 충돌 유형을 자동 분류하는 파이프라인을 만들어 1년 치 생산 환경 코어 덤프 전체를 분석했다고 밝혔다.
이 접근으로 두 개의 충돌 집단이 구분됐다. 스택 포인터가 어긋난 충돌은 특정 지역과 시작 시점, 특정 물리 호스트와 맞물렸다. OpenAI는 해당 호스트를 제외한 뒤 같은 유형의 충돌이 사라졌다고 설명했다. 반면 복귀 주소가 NULL처럼 보인 충돌은 여러 클러스터와 지역에 퍼져 있었고, 예외 언와인딩 과정과 연결됐다.
OpenAI의 분석은 GNU libunwind의 `_Ux86_64_setcontext` 구현으로 이어졌다. 회사는 이 함수가 스택 포인터를 조정한 뒤에도 기존 스택에 놓인 `ucontext_t` 구조체를 읽는 경로가 있었고, 그 사이 신호가 도착하면 커널이 신호 프레임을 만들면서 해당 메모리를 덮어쓸 수 있다고 설명했다. OpenAI는 이 경쟁 조건이 x86_64 C++ 예외 언와인딩을 지원한 초기 버전부터 존재한 18년 이상 된 문제라고 밝혔다.
경쟁 창은 매우 짧았다. OpenAI는 신호가 스택 포인터 조정 직후, 다음 명령이 복귀할 명령 포인터를 읽기 전에 도착해야 문제가 발생한다고 분석했다. 평범한 환경에서는 거의 보이지 않을 수 있지만, Rockset은 부하 제어 과정에서 예외를 많이 사용하고 CPU 시간 측정을 위해 `SIGUSR2` 신호를 자주 전달했기 때문에 조건이 겹쳤다.
완화 조치도 공개됐다. OpenAI는 즉시 GNU libunwind 대신 libgcc 언와인더를 사용하도록 바꿨고, GNU libunwind에는 재현 코드와 수정 사항을 upstream으로 제출했다고 밝혔다. GitHub의 libunwind 커밋 기록에는 `_Ux86_64_setcontext`가 `%rsp`를 조정한 뒤 기존 스택에서 값을 읽지 않도록 바꾸는 수정이 반영돼 있다.
이번 사례는 대규모 인프라 장애 분석에서 개별 사례를 깊이 보는 방식만으로는 부족할 수 있음을 보여준다. 코어 덤프 전체를 하나의 모집단으로 보고 패턴을 찾자, 하드웨어 결함과 오픈소스 런타임 버그가 한꺼번에 섞여 있던 상황이 분리됐다. AI 서비스가 더 큰 데이터 인프라와 저수준 런타임 위에서 동작하는 만큼, 관측 가능성과 자동 분석 체계의 중요성도 함께 커지고 있다.
다만 GNU libunwind 수정이 정식 릴리스와 각 배포판 패키지에 언제 반영되는지는 별도 확인이 필요하다. C++ 예외 처리, 신호 처리, libunwind 의존도가 높은 시스템을 운영하는 팀은 upstream 수정과 배포판 보안·업데이트 채널을 함께 추적해야 한다.
출처: OpenAI Engineering https://openai.com/index/core-dump-epidemiology-data-infrastructure-bug/
출처: GNU libunwind GitHub https://github.com/libunwind/libunwind/commit/a9b9293b286c14b9ed19db501aa347b46edd8a28









