본문으로 건너뛰기
피드

아폴로 11호 유도 컴퓨터에서 57년간 숨어있던 미발견 버그를 찾아냄

general 약 9분
vote
0
댓글
북마크

JUXT팀이 오픈소스 행동 명세 언어 Allium과 Claude를 사용해 아폴로 유도 컴퓨터(AGC)의 자이로 제어 코드에서 57년간 발견되지 않았던 리소스 락 누수 버그를 찾아냈다. 에러 경로에서 LGYRO 락을 해제하지 않는 결함으로, 누락된 코드는 단 4바이트. 기존 코드 리뷰와 에뮬레이션으로는 잡을 수 없었던 걸 리소스 생명주기 모델링으로 발견한 사례다.

  • 1

    AGC 자이로 제어 코드의 BADEND 에러 경로에서 LGYRO 락 미해제 — 누락 코드 4바이트

  • 2

    케이징 후 재시작 없이 자이로 재사용 시 모든 자이로 조작이 영구 블로킹

  • 3

    Allium + Claude로 13만 줄 어셈블리를 1만 2,500줄 행동 명세로 증류하여 발견

  • 4

    AGC의 방어적 코딩(재시작 시 메모리 초기화)이 오히려 버그를 57년간 은폐

  • 5

    현대 코드에서도 CWE-772(리소스 미해제) 패턴은 여전히 흔한 문제

  • 역사상 가장 많이 분석된 코드베이스 중 하나인 아폴로 유도 컴퓨터(AGC) 코드에서 57년간 아무도 발견하지 못한 버그를 찾아냄
    • 자이로 제어 코드의 에러 경로에서 리소스 락(LGYRO)을 해제하지 않는 결함
    • 누락된 코드는 딱 2줄, 4바이트 — CAF ZERO / TS LGYRO
    • 수천 명의 개발자가 읽었고, 에뮬레이터로 명령어 하나하나 검증했지만 못 찾은 걸 행동 명세(behavioral specification) 접근법으로 잡아냄

버그의 정체

  • AGC는 자이로스코프를 토크할 때 LGYRO라는 공유 락을 획득함 — 두 루틴이 동시에 자이로 하드웨어를 건드리지 못하게 하는 장치
    • 정상 완료 시 STRTGYR2 경로로 나가면서 락 해제 → 문제없음
    • 하지만 케이징(caging) 중에 토크가 진행되면 BADEND 경로로 빠지는데, 여기서 락을 안 풀어줌
  • BADEND는 범용 종료 루틴이라 일반 리소스(MODECADR 등)는 제대로 정리함
    • 문제는 LGYRO가 자이로 토크 코드에서만 쓰는 특수 락이라 BADEND가 존재 자체를 모른다는 것
  • 한번 LGYRO가 걸리면? 이후 모든 자이로 조작이 영원히 블로킹됨
    • 정밀 정렬, 드리프트 보정, 수동 자이로 토크 전부 먹통
    • 알람도 안 뜨고, 프로그램 라이트도 안 들어옴 — 그냥 명령을 받고 아무것도 안 함

중요

> 하드 리셋하면 해결되지만, 이 버그의 증상은 하드웨어 고장처럼 보임. 명령은 받아들이는데 동작만 안 하니까 소프트웨어 문제를 의심할 단서가 전혀 없음

마이클 콜린스가 혼자 달 뒤를 돌 때

  • 1969년 7월 21일, 암스트롱과 올드린이 달 표면에 있는 동안 콜린스는 사령선 컬럼비아호에서 혼자 달 궤도를 돌고 있었음
    • 2시간마다 달 뒤로 사라지면서 지구와 통신 두절
    • 매 패스마다 Program 52(별 관측 정렬)를 실행해서 유도 플랫폼 방향을 유지해야 했음 — 이게 틀어지면 귀환 엔진 점화 방향이 빗나감
  • 만약 콜린스가 좁은 조종석에서 움직이다 팔꿈치로 케이지 스위치를 건드렸다면?
    • P52 실패 → 케이지 해제 후 재정렬 시도 → 두 번째 P52가 영원히 멈춤
    • 첫 번째 실패는 정상적인 상황이라 훈련받은 대로 대응하지만, 두 번째 행(hang)은 원인을 알 수 없음
    • "지난 6개월간 나의 비밀스런 공포는 그들을 달에 두고 혼자 지구로 돌아오는 것이었다" — 콜린스 자서전 Carrying the Fire

어떻게 찾았나

  • JUXT팀이 오픈소스 행동 명세 언어 AlliumClaude를 사용해서 발견
    • AGC 어셈블리 13만 줄을 1만 2,500줄의 행동 명세로 증류(distill)
    • 명세는 코드 자체에서 파생 — 공유 리소스의 생명주기를 모델링함 (획득 → 보유 → 해제)
  • 핵심 접근 차이: 기존 검증은 "코드가 작성된 대로 동작하는가"를 확인, 행동 명세는 "코드가 무엇을 위한 것인가"를 질문함
    • gyros_busy = true가 되면, 모든 경로에서 반드시 false로 돌려야 한다는 의무를 명시적으로 선언
    • Claude가 gyros_busy = true 이후의 모든 경로를 추적 → 정상 경로는 해제하지만 BADEND 경로는 해제 안 하는 걸 발견
sequenceDiagram
    participant 토크코드 as 토크 코드
    participant LGYRO as LGYRO 락
    participant 자이로 as 자이로 하드웨어
    participant 케이지 as 케이지 이벤트

    토크코드->>LGYRO: 락 획득 (gyros_busy = true)
    토크코드->>자이로: 축별 토크 펄스 전송
    케이지-->>토크코드: 케이지 감지 (CAGETEST)
    토크코드->>토크코드: BADEND로 분기
    Note over LGYRO: ⚠️ 락 해제 누락!
    토크코드->>토크코드: 다음 P52 시도
    토크코드->>LGYRO: 락 획득 시도 → 영원히 대기

왜 57년간 안 잡혔나

  • AGC 코드가 워낙 방어적으로 작성돼서 오히려 버그가 숨음
    • 재시작 로직이 전체 소거 메모리를 초기화하면서 LGYRO도 부수효과로 클리어함
    • 테스트 중 우연히 재시작이 발생하면 시스템이 매끄럽게 복구돼서 문제가 드러나지 않음
  • 기존 검증 방식의 한계가 명확히 드러남
    • 코드 리뷰: BADEND만 보면 모든 리소스를 올바르게 정리하는 것처럼 보임
    • 에뮬레이션: 특정 시나리오를 테스트하는 거라 "케이지 후 재시작 없이 다시 토크"라는 경로를 아무도 안 돌려봄
    • 형식 검증/정적 분석: AGC 비행 코드 대상으로 발표된 논문이 없음

현대 코드에 주는 교훈

  • 마가렛 해밀턴 팀이 '소프트웨어 엔지니어링'이라는 용어 자체를 만들었고, 우선순위 스케줄링/비동기 멀티태스킹/재시작 보호 같은 개념을 선도함
    • 아폴로 11호 착륙 중 1202 알람이 발생했을 때 저우선순위 태스크를 버리는 방식으로 대응 — 현대 시스템 대부분이 이만큼 우아하게 과부하를 처리하지 못함
  • 현대 언어들이 구조적으로 락 누수를 막으려 시도하지만 여전히 한계가 있음
    • Go의 defer, Java의 try-with-resources, Python의 with, Rust의 소유권 시스템
    • 하지만 DB 커넥션, 분산 락, 셸 스크립트의 파일 핸들, 인프라 해체 순서 등은 여전히 프로그래머 책임
    • MITRE는 이 패턴을 CWE-772("유효 수명 이후 리소스 미해제")로 분류하고 악용 가능성을 '높음'으로 평가

💡

> AGC에서 표면화된 가장 심각한 버그들은 코딩 실수가 아니라 명세 오류였음. 유명한 1202 알람도 랑데부 레이더 ICD에서 위상 동기화 언급을 빠뜨린 명세 문제가 원인. 테스트는 "코드가 맞는지"를 검증하지만, 행동 명세는 "코드가 뭘 해야 하는지"를 질문함


기술 맥락

  • 행동 명세(Behavioral Specification) 가 기존의 코드 리뷰나 에뮬레이션과 근본적으로 다른 이유가 있어요. 코드 리뷰는 "이 루틴이 제대로 정리하는가"를 확인하는데, 행동 명세는 반대 방향에서 "이 리소스가 획득된 후 모든 경로에서 해제되는가"를 질문하거든요. 관점의 차이가 57년간 숨어있던 버그를 찾아낸 핵심이에요.

  • Allium은 JUXT에서 만든 오픈소스 행동 명세 언어인데, AI 네이티브를 표방해요. 13만 줄의 어셈블리를 1만 2,500줄의 명세로 증류하는 과정에서 Claude가 코드를 읽고 리소스 생명주기를 추적하는 역할을 했거든요. 사람이 어셈블리를 한 줄씩 읽는 게 아니라 AI가 모든 경로를 체계적으로 훑는 방식이에요.

  • 리소스 락 누수(CWE-772) 는 현대 코드에서도 흔한 문제예요. 언어 런타임이 관리하는 락은 deferwith 같은 구문으로 구조적으로 막을 수 있지만, 분산 락이나 DB 커넥션풀처럼 프로그래머가 직접 해제해야 하는 리소스는 여전히 같은 패턴의 버그가 발생할 수 있어요. AGC의 LGYRO가 정확히 이 케이스였고요.

  • AGC의 방어적 코딩이 오히려 버그를 은폐한 것도 재밌는 포인트예요. 재시작 로직이 메모리를 초기화하면서 락도 같이 풀려버리니까, 테스트 중에 버그가 발현돼도 시스템이 알아서 복구한 것처럼 보였거든요. "테스트 통과 = 버그 없음"이 아니라는 걸 극적으로 보여주는 사례에요.

테스트와 코드 리뷰가 '코드가 올바르게 동작하는가'를 확인하는 반면, 행동 명세는 '코드가 무엇을 해야 하는가'를 질문한다는 근본적 차이를 보여주는 인상적인 사례. AI를 활용한 대규모 레거시 코드 분석의 실용적 가능성을 입증했다.

댓글

댓글

댓글을 불러오는 중...

general

폐쇄된 클라이밋닷거브, 공공 데이터 덕분에 클라이밋닷어스로 되살아나다

미국 정부의 기후 정보 사이트 Climate.gov가 예산 삭감으로 내려간 뒤, 전직 NOAA 관련자들이 Climate.us로 핵심 자료를 복원했어. 15년 넘게 쌓인 기후 지도, 교육 자료, 기후 지표 보고서, 삭제된 제5차 국가기후평가까지 되살린 배경에는 미국 정부 데이터가 법적으로 퍼블릭 도메인이라는 점이 있었어. 다만 운영은 기부에 의존하고 있어, 공공 인프라를 민간이 임시로 떠받치는 불안정한 구조도 같이 드러나.

general

AI 시대에도 인간 관리자가 남는 이유는 결국 ‘책임’ 때문임

생성형 AI가 기업 경영의 많은 판단을 도와도, 인간 관리자의 역할이 사라지지는 않는다는 주장이다. 글은 공감, 검증, 실행, 책임이라는 네 가지 영역에서 AI가 아직 인간 관리자를 대체하기 어렵다고 설명한다.

general

서로 1만 달러 주고받으면 매출 1만 달러? 스타트업 매출 놀이를 비꼰 풍자 사이트

LARP는 창업자끼리 같은 금액을 서로 주고받은 것처럼 장부에 기록해 매출을 만든다는 설정의 풍자 사이트다. 실제 제품, 고객, 현금 이동 없이도 연간 반복 매출(ARR)을 부풀릴 수 있다는 식으로, 스타트업의 매출 인정과 상호 거래 관행을 날카롭게 비꼰다.

general

뱅크오브아메리카, 소버린 클라우드 수요 보고 아이오노스에 매수 의견

뱅크오브아메리카가 유럽 웹 호스팅·도메인 기업 아이오노스에 매수 의견과 목표주가 37유로를 제시했다. 핵심 논리는 중소기업 대상 웹 서비스, AI 업셀링, 소버린 클라우드 수요가 맞물리며 2025년부터 2028년까지 매출과 이익이 성장할 수 있다는 것이다.

general

SDT·KT·스패로우까지, 국내 보안·클라우드·양자 업계 단신 모음

SDT는 양자 클라우드 플랫폼 큐레카에 양자내성암호를 적용하고 CUDA-Q 교육 모듈을 3개 국어로 제공하기로 했다. KT, 스패로우, 매스웍스, 아이씨티케이, 오케스트로 클라우드도 각각 메일보안, 앱 보안, 디지털 트윈, 양자보안, 공공 클라우드 전환 관련 소식을 냈다.