49.7일이라는 숫자가 왜 중요할까
오픈소스 게임 프로젝트 OpenClaw을 개발하던 팀이 이상한 현상을 발견했어요. macOS에서 TCP 네트워킹이 정확히 49.7일 후에 갑자기 작동을 멈추는 거예요. 서버를 재시작하면 다시 잘 되고, 또 49.7일이 지나면 같은 문제가 반복되고요. 도대체 이 숫자는 어디서 온 걸까요?
사실 49.7일은 시스템 프로그래밍을 해본 분이라면 "아!" 하고 감이 올 수 있는 숫자인데요. 32비트 정수로 밀리초를 셀 때 최대값인 2의 32승, 그러니까 4,294,967,296 밀리초가 바로 약 49.7일이거든요. Windows에서도 GetTickCount() 함수가 이 주기로 오버플로우되는 것으로 유명하죠.
문제의 핵심: TCP 타임스탬프 오버플로우
TCP에는 "타임스탬프 옵션"이라는 게 있어요. 이게 뭐냐면, 패킷을 주고받을 때 시간 정보를 함께 실어보내서 네트워크 지연 시간을 측정하거나, 오래된 패킷과 새 패킷을 구분하는 데 쓰는 기능이에요. RFC 7323에 정의되어 있는 표준 기능이죠.
문제는 macOS의 XNU 커널(macOS의 핵심 운영체제 코드)에서 이 TCP 타임스탬프를 관리하는 내부 카운터가 32비트 밀리초 단위로 동작한다는 거예요. 시스템이 부팅된 후 이 카운터가 계속 올라가다가, 49.7일이 지나면 32비트 최대값을 넘어서 0으로 돌아가 버려요. 이걸 "오버플로우"라고 하는데, 쉽게 말하면 자동차 계기판의 숫자가 999,999에서 다시 000,000으로 돌아가는 것과 같은 거예요.
이 오버플로우가 발생하면, 이미 연결되어 있는 TCP 소켓들의 타임스탬프 비교 로직이 꼬여버려요. 커널이 새로 들어온 패킷의 타임스탬프가 "과거"의 것이라고 잘못 판단하게 되고, 결국 정상적인 패킷을 무시하거나 연결을 끊어버리는 거죠.
이런 류의 버그가 무서운 이유
이런 시간 기반 버그는 디버깅하기가 정말 어려워요. 첫째, 재현하는 데 49.7일이 걸리잖아요. 둘째, 증상이 "네트워크가 안 된다"라는 일반적인 현상이라 원인을 TCP 타임스탬프까지 추적하기가 쉽지 않아요. 셋째, 테스트 환경에서는 보통 서버를 자주 재시작하기 때문에 절대 발견되지 않는 버그이기도 하고요.
비슷한 사례로, 과거에 Windows에도 49.7일 관련 버그가 여러 차례 있었어요. 대표적으로 Windows 95에서 49.7일 후 시스템이 멈추는 버그가 있었고, 이후에도 다양한 드라이버와 네트워크 스택에서 비슷한 문제가 꾸준히 발견됐죠. Boeing 787 드림라이너도 248일(2의 32승을 centisecond 단위로 세면 약 248일) 연속 가동 시 전력 시스템이 리셋되는 유사한 종류의 버그가 보고된 적이 있어요.
업계 맥락: 왜 2025년에도 이런 버그가 나올까
"아직도 32비트 오버플로우 버그가?"라고 생각하실 수 있는데, 사실 이런 종류의 문제는 끊임없이 나와요. 이유는 간단해요. 커널 코드나 저수준 네트워크 스택은 수십 년 전에 작성된 코드가 지금까지 이어져 오는 경우가 많거든요. macOS의 XNU 커널도 FreeBSD와 Mach 커널에 뿌리를 두고 있는데, 그 시절에는 시스템이 49.7일 연속으로 돌아갈 일이 거의 없었으니까요.
Linux에서는 이 문제를 상대적으로 일찍 인지하고 TCP 타임스탬프의 오버플로우를 적절히 처리하도록 패치했는데, macOS는 아직 이 부분이 미흡했던 거예요. Apple의 서버 시장 점유율이 낮다 보니, 서버가 수십 일 이상 연속 가동되는 시나리오에 대한 테스트가 상대적으로 덜 이루어진 것 같아요.
한국 개발자에게 주는 시사점
macOS를 개발 머신으로 쓰는 분들이 많죠. 특히 로컬에서 개발 서버를 띄워놓고 오래 쓰시는 분, 또는 Mac mini를 간이 서버로 돌리시는 분들은 이 버그에 영향을 받을 수 있어요. 시스템 업타임이 49일을 넘기기 전에 재부팅하는 게 임시 해결책이 될 수 있겠죠.
더 큰 교훈은, 네트워크 프로그래밍을 할 때 타임스탬프나 카운터의 오버플로우를 항상 염두에 둬야 한다는 거예요. 직접 TCP 스택을 건드리지 않더라도, 내부적으로 시간 기반 로직을 쓸 때 32비트 범위를 넘기는 상황을 고려하는 습관이 중요해요. 특히 IoT 기기나 임베디드 시스템처럼 오래 켜두는 장비를 다루는 분들에게는 필수적인 체크 포인트예요.
정리
핵심은 이거예요: "오래 안 끄면 터지는 버그"는 아직도 현역이고, 심지어 macOS 커널에도 숨어 있었다. 여러분의 시스템에도 혹시 49.7일, 혹은 2의 32승 어딘가에서 시한폭탄처럼 째깍거리는 코드가 있지는 않은지, 한번 점검해 보는 건 어떨까요?
🔗 출처: Hacker News
TTJ 코딩클래스 정규반
월급 외 수입,
코딩으로 만들 수 있습니다
17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공