3P by GN⁺ 13시간전 | ★ favorite | 댓글 1개
  • DOOM 엔진의 변수 오버플로우로 인한 게임 크래시 현상 발생 확인
  • 실 사용 환경에서 2.5년 간 DOOM 실행 실험 진행
  • 변수 값이 계속 증가하면서, 오버플로우에 도달해 예상된 순간 게임 종료 발생
  • 실험은 PDA와 DIY UPS를 이용해 장기간 자동 실행 환경에서 진행
  • 이 테스트는 이론적 문제점이 현실에서도 실제로 발생함을 입증함

실험 배경 및 동기

  • 약 2년 반 전, DOOM 엔진 구조와 동작 방식에 관한 글을 읽으면서 데모 실행 추적에 사용되는 변수가 각 데모 시작마다 계속 증가함을 발견함
  • 이 변수는 직전 값과 비교가 이루어지지만, 반복적으로 값이 커지면서 결국 오버플로우 위험이 내재함
  • 평범한 사용 환경에서는 이 오버플로우 상황에 도달하기 어렵지만, 실제로 얼마나 걸리는지 직접 실험 진행 결정

실험 방법 및 과정

  • 단순 계산을 통해 오버플로우가 일어나기까지 약 2년 반의 런타임이 필요하다고 추정함
  • 실제 확인을 위해 PDA 기기에 DOOM을 설치 후, 18650 배터리를 사용한 DIY UPS로 전원을 공급
  • 해당 기기를 라우터 USB 포트에 연결하여 5V 전원 공급을 지속적으로 유지함
  • 시스템을 자동충전 환경에서 지속 구동하도록 세팅 후, 대부분의 시간 동안 방치함

크래시 발생 및 결과

  • 실험 시작 약 2년 반이 지난 후, 기기의 화면에 팝업 알림이 등장함을 확인
  • DOOM이 예상과 같이 오버플로우로 인한 하드 크래시 상태로 전환됨
  • 실험 결과, 변수 오버플로우로 인한 게임 종료 현상이 실제 하드웨어, 실제 소프트웨어 환경에서도 발생함을 입증함

결론 및 시사점

  • 프로그래밍에서 긴 시간 동안 누적되어 증가하는 변수에 대한 주의점 강조
  • 이론상 가능성으로만 여겨지던 오버플로우 문제가 현실에서 실제로 터질 수 있음을 실험적으로 확인함
  • 레거시 코드 혹은 장시간 동작하는 소프트웨어의 숨어있는 결함에 대한 경각심 고취
Hacker News 의견
  • 약 1년 전 Crash Bandicoot의 타이머 시스템을 살펴보던 중 Crash 3에서는 int32 타입의 값이 계속 증가함을 발견했음, 죽을 때만 리셋되는 구조임, 2.26년 동안 켜두면 오버플로우가 발생함, 이때 '마이너스' 시간이 되어 게임이 여러 가지 웃긴 방식으로 망가짐, 이에 대한 영상을 제작함 YouTube 링크

    • Final Fantasy 9에는 특정 무기를 얻으려면 12시간(유럽 버전은 10시간) 이내에 후반부 지역에 도달해야 하는데, 버그 때문에 타이머가 오버플로우될 때까지 2년 동안 계속 켜두어도 획득 가능함, 느긋하게 기다려도 목적 달성임, 자세한 설명 링크

    • 당신 영상에서 "crash"라는 말장난을 한 번도 하지 않은 점이 신기함, 프리즈 현상도 crash라 부를 수 있었을 텐데 약간 아쉬움

    • 타이머 추적에 대해 signed integer를 기본값으로 사용하는 것이 흔한지 궁금함, unsigned라면 오버플로우까지 시간이 두 배는 늘어날 텐데 왜 그런 선택을 했을까 의문임

    • 많은 게임이 그런 구조였던 것으로 생각함, SotN도 글로벌 타이머가 있음, 32비트 시스템에서 몇 달 ~ 길어야 몇 년 사용되는 게임을 위해 굳이 수년의 경과를 테스트할 필요성을 못 느꼈음, 아무도 본인이 만든 소프트웨어가 해킹, 분석, 역공학까지 당할 거라고는 그 당시엔 상상하지 못했을 것임, 우리도 평소 프로그램 작성할 때 그런 점을 크게 고려하지 않음

    • 진정한 Time Twister 해금임

  • 플레이가 불가능하다고 느껴질 만한 상황임, 누군가가 꼭 고쳐줬으면 하는 바람임, Doom은 정말 훌륭한 게임이고 수년마다 항상 다시 찾아 하게 됨, 2016년 리부트도 재미있었지만, 그 이후 타이틀은 개인적으로 별로였음

    • 클래식 Doom 스타일 게임플레이를 선호하는 사람들을 위한 커뮤니티가 있음 r/boomershooters

    • 나도 마찬가지임, 최근 타이틀에서의 메트로이드바니아 디자인과 홈 허브 구조는 예전 느낌을 주지 못함, 달리고, 적을 처치하고, 비밀을 찾고, 다음 레벨로 이동하는 단순한 진행 방식이 더 좋은 느낌임

    • 나 역시 같음, 특히 brutality 모드를 매우 좋아함

    • 흥미로운 사실임, 이제 Doom은 Quake, StarCraft, WarCraft, Overwatch, Infocom과 Sierra의 모든 어드벤처 게임, 그리고 Halo와 함께 Microsoft 소유임, Microsoft는 1996년부터 PC 게임 대부분의 지적재산권을 차지하려 했으니 거의 목적을 달성한 셈임

    • 2016년작은 내가 해본 최고의 싱글 플레이 FPS임, 그와 비견될 만한 건 Titan Fall 2밖에 없었음

  • 하드웨어에서 오버플로우를 트랩하는 기능이 있는지 궁금함, Doom 엔진 동작에 관한 글을 읽고 데모 추적 변수가 다음 데모가 시작되어도 계속 증가한다는 점을 봤음, 이 변수는 이전 값을 저장하는 두 번째 변수와 비교함, 실제 게임이 왜 크래시가 발생했는지 궁금함

    • C 언어에서 signed overflow는 정의되지 않은 동작이기 때문에 결과가 예측 불가임, 하지만 이 경우 플랫폼이나 컴파일러에 상관없이 동일하게 발생하는 걸로 봐선 그 문제가 아닌 듯함, 본문(TFA)에 따르면 이 변수는 그 이전 값과 비교되고, new < old 상황이 발생할 거라고 생각하지 않은 채 코딩되어 있음, 이 때문에 스택 손상 같은 버그가 쉽게 발생할 수 있음, C는 예를 들어 return 값이 없는 함수가 값을 반환해야 하는 상황에 도달하면 아무렇지 않게 정의되지 않은 동작을 실행함
  • 버그 원인을 미리 알고 있었다는 점에 감사해야 함, 2.5년 지나고 나서야 "젠장, 디버그 로그를 켜는 걸 깜빡했네"라고 깨달았을 수도 있음

  • DOOM이 Windows CE보다 먼저 크래시가 발생했음

    • 2.5년 동안 PDA에서 애플리케이션이 계속 돌아간 것에 가장 감탄함, 인터넷이 끊어진 채로 최신 하드웨어에서 이런 일이 가능할지 매우 의문임

    • 정말 대단한 기록임

  • 사이트가 너무 많은 접속으로 다운된 듯하여 archive.org 링크를 제공함 https://lenowo.org/viewtopic.php?t=31">archive.org 저장본 링크, 아쉽게도 사이트 포맷은 다 저장되지 않았지만 텍스트는 남아있음

  • 2038년이 흥미로울 한 해가 될 것 같음

    • 많은 사람들이 2036년에 있을 NTP 문제는 간과함, 그때가 진짜 파티 시작임

    • y2k 시절보다 2038년이 훨씬 더 가까이 느껴짐

    • 64비트 int로 업그레이드하거나 time_t를 long long 타입으로 전환하는 데 13년 남았음, 많은 임베디드 장비나 지원 중단된 폐쇄형 시스템은 별도의 주의가 필요할 것임, 예전에 사용하던 SunServer 600MP의 OpenFirmware에도 동일한 문제가 있었음, 다행히 이제는 걱정하지 않아도 되는 문제임

    • 그 문제를 해결하는 것이 나의 은퇴 계획임

  • 이 정도 수준의 테스트는 내가 아는 어떤 테스터들도 하지 않을 것임, 내가 일하는 시스템에서도 어제만 해도 30초 타임아웃 후 에러 처리를 확인하려고 5번 이상 기다려야 했는데, 매우 짜증나는 일이었음

  • 한때 Windows NT 4에도 비슷한 버그가 있었음, 시스템의 uptime을 측정하는 고정밀 카운터였음, Service Pack 3(또는 2) 이전에는 매달 1일 마다 스케줄러로 시스템을 재부팅해줬음, 그렇지 않으면 약 42일 uptime 후에 크래시가 발생했음, Microsoft조차도 오랜 시간 서버 OS가 계속 돌아갈 거라 생각하지 않았던 것임

  • id Software 팀에게 다시 한 번 찬사를 보냄, 요즘 일반적인 방식으로 개발됐다면 메모리 단편화나 메모리 누수 문제로 2년을 넘기기도 전에 죽었을 것임