Claude Code를 사용하다가 ‘exit code 137’이라는 메시지를 본 적이 있나요? 이 에러는 특정한 시스템 신호로 인한 프로세스 강제 종료를 의미해요. 오늘은 이 exit code의 의미와 해결 방법을 알아보겠습니다.
프로그래밍 환경에서 오류가 발생할 수 있는 원인은 매우 다양해요. 코드 자체의 논리 오류부터 시작해서, 메모리 부족, 시스템 리소스 초과, 그리고 외부 신호에 의한 강제 종료까지 여러 가지가 있습니다. Exit code 137은 이 중에서 특정 신호에 의한 종료를 나타내요.
Exit Code 137의 정체
Exit code 137은 수학적으로 128 + 9를 의미해요. 이는 SIGKILL(신호 9)로 인한 프로세스 강제 종료를 나타냅니다. SIGKILL은 운영체제가 프로세스를 즉시 종료시키는 신호로, 프로세스가 이를 무시하거나 처리할 수 없어요.
SIGKILL 신호는 여러 상황에서 발생할 수 있어요. 사용자가 명시적으로 강제 종료를 요청했거나, 시스템이 리소스 부족으로 인해 프로세스를 강제 종료했거나, 또는 관리자가 의도적으로 프로세스를 중단시킨 경우죠.
신호(Signal)의 개념
Unix/Linux 시스템에서 신호는 프로세스 간의 통신 메커니즘이에요. 특정 이벤트가 발생하면 운영체제가 해당 프로세스에게 신호를 보내고, 프로세스는 그 신호에 반응해서 특정 작업을 수행하게 됩니다.
예를 들어 SIGTERM(신호 15)은 정상적인 종료를 요청하는 신호고, SIGINT(신호 2)는 사용자가 Ctrl+C를 눌렀을 때 발생하는 신호예요. SIGKILL(신호 9)은 이런 신호들과 달리 무조건 프로세스를 종료시키는 신호라서 특별해요.
Claude Code에서 Exit Code 137 발생 원인
Claude Code 환경에서 exit code 137이 발생하는 주요 원인들을 살펴보면 다음과 같아요:
- 메모리 부족으로 인한 Out-of-Memory(OOM) 킬러의 프로세스 강제 종료
- 실행 시간 초과로 인한 타임아웃
- 수동으로 프로세스 중단 (사용자가 중단 버튼 클릭)
- 리소스 제한 초과 (CPU, 메모리 등)
- 시스템 관리자에 의한 프로세스 강제 종료
- 프로그램이 무한 루프에 빠진 경우
메모리 부족 상황
가장 흔한 원인은 메모리 부족이에요. 프로그램이 사용할 수 있는 메모리를 초과하면, 운영체제의 OOM(Out-of-Memory) 킬러가 해당 프로세스를 강제 종료시킵니다. 특히 대용량 데이터를 처리하거나, 메모리 누수가 있는 프로그램에서 이런 일이 발생하기 쉬워요.
메모리 문제는 프로그램의 알고리즘이나 데이터 구조에 문제가 있을 때 주로 발생합니다. 예를 들어 배열의 크기를 미리 전부 할당하거나, 메모리를 해제하지 않고 계속 할당하는 경우죠.
무한 루프와 타임아웃
프로그램이 무한 루프에 빠지면, 실행이 영원히 끝나지 않게 되어요. Claude Code 같은 환경에서는 이런 상황을 방지하기 위해 타임아웃(timeout)을 설정해두고 있어요. 정해진 시간 내에 프로그램이 종료되지 않으면, 시스템이 강제로 프로세스를 중단시키는 거죠.
무한 루프는 다양한 상황에서 발생할 수 있어요. 잘못된 조건문으로 인해 루프가 끝나지 않는 경우, 재귀 함수가 끝나지 않는 경우, 또는 외부 입력을 기다리는 상황에서 입력이 없는 경우가 그 예입니다.
타임아웃 감지 방법
프로그램이 exit code 137로 종료되었다면, 먼저 무한 루프나 타임아웃이 원인인지 확인해보세요. 다음과 같은 방법들을 시도해볼 수 있어요:
- 코드에 진행 상황을 나타내는 print 문 추가
- 실행 시간을 예상해서 내부적으로 제한
- 반복문이 제대로 종료되는지 확인
- 재귀 깊이에 제한 두기
- 외부 입력 기다리기를 없애거나 제한시간 두기
메모리 최적화
메모리 부족으로 인한 exit code 137을 방지하려면 메모리 사용을 최적화해야 해요. 몇 가지 효과적인 방법들을 소개합니다:
첫째, 불필요한 데이터 복사를 피하세요. 큰 리스트나 배열을 함수에 전달할 때는 복사 대신 참조를 사용하면 메모리를 절약할 수 있어요. Python의 경우 리스트 슬라이싱이나 문자열 연결도 새로운 객체를 만드는 작업이므로 주의해야 합니다.
둘째, 제너레이터(generator)나 이터레이터(iterator)를 사용해서 한 번에 전체 데이터를 메모리에 로드하지 않도록 하세요. 대용량 파일을 처리할 때 특히 효과적이에요.
효율적인 자료구조 선택
사용하는 자료구조도 메모리 사용량에 큰 영향을 미쳐요. 예를 들어 파이썬의 리스트(list)는 각 요소마다 추가적인 메모리를 사용하지만, 같은 타입의 수치를 저장할 때는 array나 numpy 배열을 사용하면 더 효율적이에요.
실행 시간 최적화
타임아웃으로 인한 exit code 137을 방지하려면 코드의 실행 시간을 줄여야 해요. 다음과 같은 방법들이 도움이 됩니다:
- 알고리즘의 시간 복잡도 개선 (예: O(n²) → O(n log n))
- 반복 횟수가 많은 부분 최적화
- 불필요한 계산이나 I/O 작업 제거
- 캐싱이나 메모이제이션(memoization) 사용
- 병렬 처리 활용
프로파일링(Profiling)
코드가 어디서 시간을 소비하는지 파악하는 것이 중요해요. Python의 경우 cProfile이나 timeit 같은 도구를 사용해서 각 함수의 실행 시간을 측정할 수 있습니다. 시간을 가장 많이 소비하는 부분부터 최적화하는 것이 효율적이에요.
재귀와 반복
재귀 함수를 사용할 때 특히 주의해야 해요. 재귀 깊이가 너무 깊으면 스택 오버플로우가 발생할 수 있고, 이로 인해 프로세스가 강제 종료될 수 있기 때문입니다.
가능하면 재귀 대신 반복(iteration)을 사용하는 것이 안전해요. 반복은 스택을 사용하지 않으므로, 메모리 부족 문제가 덜 할 수 있거든요. 만약 재귀를 사용해야 한다면, 최대 깊이를 제한하거나 메모이제이션으로 불필요한 계산을 줄이세요.
스택 깊이 확인
Python에서는 sys.getrecursionlimit()로 최대 재귀 깊이를 확인할 수 있어요. 기본값은 보통 1000이지만, 필요에 따라 줄이거나 늘릴 수 있습니다. 다만 너무 크게 설정하면 스택 오버플로우가 발생할 수 있으니 주의해야 합니다.
테스트와 검증
프로그램이 정상적으로 작동하는지 확인하는 것이 중요해요. 다음과 같은 테스트를 수행해보세요:
- 작은 입력값으로 테스트 (메모리/시간 문제 확인)
- 경계값 테스트 (입력값의 최대/최소값)
- 무한 루프 여부 확인
- 메모리 누수 확인 (long-running test)
- 타임아웃 테스트 (실행 시간 측정)
결론 및 해결 전략
Exit code 137은 대부분 메모리 부족, 타임아웃, 또는 무한 루프로 인한 프로세스 강제 종료를 의미해요. Claude Code에서 이 에러가 발생했다면, 먼저 코드가 무한 루프에 빠지지 않았는지 확인하고, 메모리 사용을 최적화하며, 실행 시간을 단축해야 합니다.
문제를 해결할 때는 체계적으로 접근해보세요. 먼저 코드에 진행 상황 출력을 추가해서 어디서 멈추는지 확인하고, 해당 부분을 집중적으로 분석해봐요. 메모리 사용이 문제라면 자료구조와 알고리즘을 개선하고, 실행 시간이 문제라면 시간 복잡도를 개선하세요. 이런 과정을 통해 대부분의 exit code 137 문제는 해결할 수 있어요.