1. 개요
보통 순수한 Java 코드만 사용하여 개발하는 경우에는 OS core 파일이 발생할 가능성이 매우 낮다. 하지만 JNI(Java Native Interface)를 통해 구현한 네이티브 모듈에서 문제가 발생하면 Java 프로세스가 core 파일을 생성하고 종료되는 경우를 종종 볼 수 있다.
core 파일은 프로세스가 비정상 종료된 시점의 메모리 상태를 담고 있으므로, gdb 같은 디버거로 당시 어떤 네이티브 함수나 스레드에서 문제가 발생했는지 확인하는 데 사용할 수 있다. Java 애플리케이션이라도 네이티브 라이브러리, JVM 내부, OS 라이브러리 문제가 의심될 때는 core 분석이 도움이 된다.
2. 사용법
$ gdb 실행파일 core파일
여기서 실행파일은 core를 생성한 실제 바이너리다. Java 프로세스의 core를 분석한다면 일반적으로 해당 JVM의 java 실행 파일을 지정한다.
3. 사용예
$ gdb /usr/java5/bin/java core
분석 정확도를 높이려면 core가 생성된 서버와 동일한 실행 파일, 동일한 네이티브 라이브러리, 가능하면 디버그 심볼을 함께 준비하는 것이 좋다.
4. 명령어(OS마다 조금씩 다를 수 있음)
where또는bt: 종료 시점에 해당 프로세스가 수행하던 호출 스택 확인info threads: 전체 스레드 목록 확인thread apply all bt: 모든 스레드에 대한 stack trace 정보 출력
특정 스레드가 의심되면 thread 번호로 스레드를 전환한 뒤 bt를 실행해 해당 스레드의 호출 흐름을 확인할 수 있다.
5. 기타 환경 변수
ulimit -c: core file 생성 가능 최대 크기 확인ulimit -c unlimited: core file 크기 제한 해제ulimit -c 5000: core file 최대 크기를 5000으로 제한. 단위는 셸과 OS 설정에 따라 다를 수 있으므로 해당 환경의 문서를 확인해야 한다.
core 파일이 생성되지 않는다면 먼저 ulimit -c 값이 0인지 확인하고, OS의 core dump 설정 및 저장 경로도 함께 점검해야 한다.
6. 활용 사례
- AIX 서버에서 WAS 사용 중 Hang 현상 발생
- 분석해보니 PosixSocketMuxer에서 Segmentation Error 발생
- 더 자세히 분석하니 Hang 상황 시에 특정 함수가 호출되는 것을 확인
- OS Bug임을 확인