
달의 뒷면에서 잠들어 있던 버그
1969년, 인류를 달에 보낸 아폴로 11호. 그 우주선을 제어하던 AGC(Apollo Guidance Computer)의 소스코드가 GitHub에 공개된 건 이미 꽤 알려진 이야기인데요. 그런데 최근 한 개발팀이 이 코드를 정밀 분석하다가, 지금까지 누구도 문서화하지 않았던 버그를 하나 찾아냈어요. 57년 동안 아무도 모르고 있었던 버그라니, 생각만 해도 소름이 돋지 않나요?
이 버그를 발견한 건 영국의 소프트웨어 컨설팅 회사 JUXT의 팀이에요. 이들은 AGC 코드를 현대적인 도구로 시뮬레이션하면서 분석하고 있었는데, 달의 뒷면을 돌 때 실행되는 특정 루틴에서 예상과 다른 동작을 발견한 거예요.
어떤 버그였을까?
AGC가 하는 일 중 하나는 우주선의 위치와 속도를 계속 계산하는 건데요. 이걸 항법(navigation)이라고 해요. 쉽게 말하면, "지금 우리가 어디에 있고, 어디로 가고 있는지"를 실시간으로 추적하는 거예요. 이 계산에는 지구와 달의 중력이 모두 반영되어야 하거든요.
문제는 달의 뒷면을 돌 때 발생했어요. 우주선이 달 뒤로 넘어가면 지구와의 통신이 끊기잖아요. 이때 AGC는 완전히 자율적으로 동작해야 하는데, 바로 이 구간에서 중력 계산에 쓰이는 변수 하나가 잘못 처리되고 있었어요.
좀 더 구체적으로 설명하면, AGC는 제한된 메모리(겨우 약 74KB!)에서 동작하다 보니 하나의 메모리 주소를 여러 용도로 재사용하는 경우가 많았어요. 이게 뭐냐면, 요즘 코드로 치면 하나의 전역 변수를 여기저기서 다른 의미로 쓰는 것과 비슷한데요. 당시에는 메모리가 너무 귀했기 때문에 어쩔 수 없는 선택이었죠. 그런데 이 과정에서 특정 타이밍에 값이 덮어씌워지는 레이스 컨디션(race condition) 비슷한 상황이 생길 수 있었던 거예요. 레이스 컨디션이란, 두 개의 작업이 같은 데이터를 동시에 건드려서 예상치 못한 결과가 나오는 걸 말해요. 마치 두 사람이 동시에 같은 문서를 편집하면 내용이 꼬이는 것처럼요.
이 버그가 실제로 발동했다면, 항법 계산에 미세한 오차가 누적될 수 있었어요. 다행히 실제 아폴로 11호 미션에서는 이 버그가 치명적인 영향을 주지 않았을 가능성이 높다고 분석팀은 말하고 있어요. 달 뒷면을 도는 시간이 상대적으로 짧았고, 오차가 누적될 만큼의 시간이 없었기 때문이에요. 하지만 만약 더 긴 시간 동안 자율 항법에 의존했다면? 이야기가 달라졌을 수도 있죠.
57년 동안 왜 아무도 못 찾았을까?
이건 사실 당연한 면이 있어요. AGC 코드는 어셈블리 언어로 작성되어 있거든요. 어셈블리란, 기계어에 거의 가까운 저수준 언어인데, 읽기가 정말 어려워요. 변수 이름도 MPAC, ETEFLAG 같은 약어투성이고, 주석도 당시 엔지니어들만 이해할 수 있는 방식으로 쓰여 있어요.
게다가 이 코드를 실제로 실행해볼 환경을 만드는 것 자체가 큰 과제예요. JUXT 팀은 AGC의 동작을 소프트웨어로 재현하는 시뮬레이터를 활용했는데, 이런 도구가 최근에야 충분히 성숙해졌기 때문에 지금 시점에서 발견이 가능했던 거예요. 2016년에 GitHub에 코드가 공개된 이후로 여러 사람이 분석을 시도했지만, 실제로 실행 흐름을 추적하면서 찾아내는 건 차원이 다른 작업이었던 셈이죠.
역사적 코드 분석이 주는 교훈
이 발견이 흥미로운 건, 단순히 "옛날 코드에서 버그를 찾았다"는 이야기가 아니기 때문이에요. 여기에는 현대 개발자에게도 중요한 교훈이 담겨 있어요.
먼저, 메모리 재사용의 위험성이에요. 요즘은 메모리가 넉넉하니까 이런 실수를 할 일이 적다고 생각할 수 있지만, 임베디드 시스템이나 IoT 디바이스처럼 리소스가 제한된 환경에서는 여전히 비슷한 패턴이 쓰여요. 마이크로컨트롤러로 작업하는 분들이라면 공감할 거예요.
그리고 코드 리뷰의 한계도 보여줘요. 아폴로 프로젝트에는 당대 최고의 엔지니어들이 참여했어요. MIT의 찰스 스타크 드레이퍼 연구소에서 개발했고, 테스트도 당시 기준으로는 가장 엄격하게 진행됐거든요. 그런데도 이런 버그가 남아 있었다는 건, 사람의 눈만으로는 복잡한 시스템의 모든 경우의 수를 잡아내기 어렵다는 뜻이에요. 오늘날 우리가 정적 분석 도구나 퍼징(fuzzing) 같은 자동화 검증을 중요시하는 이유이기도 하죠.
한국 개발자에게 주는 시사점
요즘 한국에서도 항공우주 분야에 대한 관심이 높아지고 있잖아요. 누리호 개발 이후 우주 산업 생태계가 커지고 있고, 관련 소프트웨어 인력 수요도 늘고 있어요. 이런 미션 크리티컬 시스템에서는 아무리 작은 버그도 치명적일 수 있다는 걸 이 사례가 잘 보여줘요.
또 하나, 레거시 코드를 분석하는 능력의 가치도 생각해볼 만해요. 57년 된 어셈블리 코드를 읽고 시뮬레이션해서 버그를 찾아내는 건, 어찌 보면 우리가 회사에서 "누가 만들었는지 모를 10년 된 코드"를 유지보수하는 것과 본질적으로 같은 일이거든요. 다만 스케일이 좀 다를 뿐이죠. 레거시 코드를 두려워하지 말고, 차근차근 실행 흐름을 따라가면서 이해하는 연습이 중요하다는 걸 다시 한번 느끼게 해주는 사례예요.
마무리
인류를 달에 보낸 코드에서 57년 만에 발견된 버그. 실제 미션에 영향을 줬을 가능성은 낮지만, 이 발견 자체가 소프트웨어 검증과 레거시 코드 분석의 가치를 다시금 일깨워 줘요.
여러분은 예전에 작성된 코드에서 아무도 모르고 있던 버그를 발견한 경험이 있나요? 그때 어떻게 추적하셨는지 궁금하네요.
🔗 출처: Hacker News
TTJ 코딩클래스 정규반
월급 외 수입,
코딩으로 만들 수 있습니다
17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공