처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.08.02 29

musl 빌드 리그렙, 초대형 트리 검색 중 간헐적 세그폴트

Hacker News 원문 보기

리그렙(ripgrep)은 러스트로 작성된 초고속 코드 검색 도구로, 개발자들이 grep 대신 널리 쓰는 커맨드라인 유틸리티다. 최근 공개된 이슈 하나는 이 도구의 특정 배포 형태에서 드물지만 재현 가능한 크래시가 발생한다는 보고다. 문제가 된 것은 x86_64-unknown-linux-musl 대상으로 빌드된 정적 바이너리로, 초대형 디렉터리 트리를 높은 동시성으로 반복 검색할 때 SIGSEGV로 죽는 현상이다. 버전은 15.2.0(rev e89fff8), PCRE2 10.45와 JIT가 활성화된 구성이다.

주목할 점은 이 바이너리의 배포 경로다. 보고자는 처음 OpenAI Codex에 번들된 rg에서 이 버그를 만났는데, 해당 바이너리가 공식 릴리스로 배포되는 musl 타르볼과 바이트 단위로 완전히 동일했다고 밝혔다. 그리고 Codex 환경과 무관하게 독립적으로 같은 크래시를 재현했다. 즉 특정 제품이 손댄 문제가 아니라, 널리 유통되는 공식 musl 빌드 자체에 내재한 현상이라는 뜻이다. 여러 도구가 리그렙 바이너리를 그대로 끌어다 쓰는 관행을 감안하면, 영향 범위가 하나의 CLI에 그치지 않을 수 있다.

크래시가 가리키는 지점

분석을 위해 보고자는 cross와 podman을 이용해 디버그 심볼을 포함한 채로 다시 빌드했다. 코어 덤프의 백트레이스에서 크래시가 난 지점은 리그렙 자체 코드가 아니라 musl의 메모리 할당자였다. 구체적으로는 opendir가 호출한 calloc 내부, mallocng(musl의 차세대 할당자)의 힙 메타데이터 무결성 검사(assertion)에서 터졌다. 이는 할당자가 자신이 관리하는 메타데이터가 손상되었음을 감지하고 방어적으로 프로세스를 중단시킨 상황을 시사한다. 다시 말해 증상이 드러난 곳은 디렉터리 열기 과정이지만, 실제 원인은 그 이전 어딘가에서 힙이 오염되었을 가능성을 가리킨다.

이 대목이 실무적으로 중요한 이유는, 힙 메타데이터 손상형 버그의 전형적 특성 때문이다. 무결성 검사가 걸린 위치와 실제로 잘못이 발생한 위치가 다를 수 있어, 크래시 지점만 보고 원인을 단정하기 어렵다. 원인 후보로는 리그렙이나 그 의존성의 메모리 취급 문제, musl mallocng 자체의 결함, 혹은 특정 동시성·부하 조건에서만 드러나는 경합 등이 모두 열려 있다. 현재 이슈는 재현 절차와 코어 덤프를 제시하는 단계이며, 근본 원인이나 수정이 확정된 상태는 아니다.

재현 조건이 말해주는 것

재현에는 충분히 큰 검색 트리가 필수로 보인다. 보고자는 LLM이 작성한 generate_repro_tree.py로 약 20GiB, 180만 개 파일 규모의 무작위 트리를 만들어 원래 버그를 만난 저장소의 통계를 흉내 냈다. 그런 다음 트리 안에 존재하지 않는 임의의 리터럴 문자열을 while 루프로 계속 검색했다. 24코어 시스템에서 트리가 커널 블록 캐시에 통째로 들어갈 만큼 여유 RAM이 있는 조건일 때, 보통 1분쯤 지나면 SIGSEGV가 나타났다.

이 조건들은 문제의 성격을 꽤 구체적으로 드러낸다. 검색어가 트리에 없다는 점은 출력 처리보다 파일시스템 순회 자체가 부하의 중심임을 뜻하고, 블록 캐시에 데이터가 모두 올라와 있어야 한다는 점은 I/O 대기 없이 CPU와 할당자가 최대 속도로 돌아가는 상황이 방아쇠임을 시사한다. 다수 코어에서 스레드가 opendir와 힙 할당을 맹렬히 반복하는 고동시성 환경, 그리고 방대한 디렉터리 수가 결합될 때에만 드물게 터지는 셈이다. 일반적인 소규모 저장소 검색에서는 사실상 마주치기 어려운 조합이다.

실무자가 기억할 점

당장 대다수 사용자에게 위험한 버그는 아니다. 발현 조건이 초대형 트리, 고코어 동시성, 반복 실행이라는 좁은 교집합이고, 크래시는 데이터 손상 없이 프로세스 중단으로 끝난다. 다만 CI 파이프라인이나 대형 모노레포를 다루는 인프라, 그리고 리그렙 musl 바이너리를 내부에 임베드한 에이전트·도구 체인이라면 사정이 다르다. 간헐적이고 재현이 까다로운 세그폴트는 원인을 다른 곳에서 찾게 만들어 디버깅 시간을 크게 갉아먹기 때문이다. glibc 기반 빌드나 배포판 패키지를 쓰는 환경이라면 애초에 이 정적 musl 바이너리 경로를 밟지 않는다는 점도 참고할 만하다.

결국 이 사례는 정적 musl 바이너리가 이식성 때문에 널리 선호되지만, 그 아래 할당자 동작이 부하 특성에 따라 미묘한 차이를 낸다는 사실을 상기시킨다. 힙 무결성 검사가 걸린 크래시를 만나면 애플리케이션 코드만 의심하기보다 실행 중인 libc와 할당자까지 시야에 넣어야 한다. 이 이슈의 다음 관전 포인트는 병목이 리그렙 쪽 메모리 취급인지, musl mallocng의 특정 조건 결함인지가 코어 덤프 분석을 통해 어디로 좁혀지느냐다.

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

AI 도구, 직접 활용해보세요

AI 시대, 코딩으로 수익을 만드는 방법을 배울 수 있습니다.

AI 활용 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.