리눅스 core dump 파일 오류 확인 방법
1. core dump 파일을 남기는지 확인
ulimit -a 명령 실행
core file size 항목이 설정되 있는 경우 가능
없다면 ulimit -c unlimited 명령으로 설정
그리고 /etc/security/limits.conf 에 아래 내용을 추가해야 재부팅시도 유지가 된다.
* - core unlimited
2. file 명령으로 어느 파일의 core dump 인지 확인
예) file core.26325
core.26325: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './frontend'
3. GDB를 사용하여 코어파일 분석
예) gdb ./frontend ./core.26325
명령설명
backtrace : 죽기직전 호출되었던 호출스택 확인
break Abnomal : 마지막 호출 함수에 break point 설정, 그 이후 r 키로 한줄씩 디버깅
---------------------------- 추가 --------------------------------------
출처 : http://cafe.naver.com/nexcore.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=43
1.1. Core Dump 파일 분석하기
1.1.1. 코어 덤프 파일 정보 보기
GDB로 코어 덤프 파일 분석하기 , gdb [프로그램명] [코어파일명]
> gdb cursorserv core.9122
HP gdb 5.8 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
. . .
backtrace 명령어로 콜스택 backtrace
(gdb) bt
#0 inline std::allocator<char>::allocator(std::allocator<char> const&) ()
at /opt/aCC/include_std/memory:252
#1 0x9fffffffbb8b7440:0 in inline std::basic_string<char,std::char_traits<char>,std::allocator<char> >::get_allocator() const ()
at /opt/aCC/include_std/string:774
#2 0x9fffffffbb8b7420:0 in std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string (this=0x9fffffffffffdb58, __s=@0x0)
at /opt/aCC/include_std/string:1035
#3 0x9fffffffbbbb2100:0 in nexcore::sql::Record::setValue (
this=0x9fffffffffffdd30, key=@0x0, value=@0x9fffffffffffdca8)
at nexcore/sql/Record.cpp:67
#4 0x9fffffffb99ec310:0 in int nexcore::sql::SqlManager::select<TestFun*,bool
(this=0x600000000006d0c0, statementId=@0x9fffffffffffde00,
params=0x9fffffffffffde30, c=0x60000000001340b0, mf=(bool ( class TestFun
::*)(class nexcore::sql::Record *...)) -147599808)
at /home/jsh/nexbuild/nana/include/nexcore/sql/SqlManager.hpp:157
#5 0x9fffffffb99e9240:0 in TestFun::perform (this=0x60000000001340b0,
request=0x6000000000141950, response=0x6000000000025840) at TestFun.cpp:103
#6 0x9fffffffbbc74510:2 in inline std::allocator<char>::allocator() ()
at /opt/aCC/include_std/memory:250
의심되는 스택 프레임으로 이동한다. 예를 들어 4번 프레임을 조사하고 싶으면, frame 4를 입력한다.
Frame 4를 선택해서 스택 정보 보기
(gdb) f 4
#4 0x9fffffffb99ec310:0 in int nexcore::sql::SqlManager::select<TestFun*,bool
(this=0x600000000006d0c0, statementId=@0x9fffffffffffde00,
params=0x9fffffffffffde30, c=0x60000000001340b0, mf=(bool ( class TestFun
::*)(class nexcore::sql::Record *...)) -147599808)
at /home/jsh/nexbuild/nana/include/nexcore/sql/SqlManager.hpp:157
157 record.setValue( colNames[i], rset->getString(i+1) );
해당 스택의 소스 보기
(gdb) list
152 while(rset->next())
153 {
154 Record record;
155 for (int i=0; i<colCount; i++)
156 {
157 record.setValue( colNames[i], rset->getString(i+1) );
158 }
159
160 // call callback function
해당 스택의 argument 보기
(gdb) info arg
this = (class nexcore::sql::SqlManager * const) 0x600000000006d0c0
statementId = (
class std::basic_string<char, std::char_traits<char>, std::allocator<char>>
&) @0x9fffffffffffde00: {_C_data = 0x600000000013a4f0 "select",
static __nullref = <optimized out>, static npos = <optimized out>}
params = (class nexcore::sql::Params *) 0x9fffffffffffde30
c = (class TestFun *) 0x60000000001340b0
mf = (bool ( class TestFun::*)(class nexcore::sql::Record *...)) (bool (
class TestFun::*)(class nexcore::sql::Record *...)) -147599808
해당 스택의 local value 보기
(gdb) info local
i = 0
record = {record = {__t = {_C_buffer_list = 0x6000000000134d40,
_C_free_list = 0x0, _C_next_avail = 0x60000000003cc650,
_C_last = 0x60000000003ccc20, _C_header = 0x60000000003cc620,
_C_node_count = 0, _C_insert_always = false,
_C_key_compare = {<std::binary_function<std::string, std::string, bool>> = {<No data fields>}, <No data fields>}}}, __vfp = 0x9fffffffbb784110}
colCount = 2
resultCount = 0
selectCnt = 0
query = {
_C_data = 0x6000000000033830 " SELECT A.NATION_CD AS nationCD, A.NATION_NM AS nationNM FROM PI_NATION A WHERE A.NATION_CD LIKE '%' || #nationCD# || '%' AND A.DEL_FLG='N' ", static __nullref = <optimized out>,
static npos = <optimized out>}
위와 같은 방식으로 코어 덤프 파일로부터 콜스택을 추적하여 프로그램이 비정상 종료된 원인을 찾아낸다. 자세한 명령어 및 검사방법은 GDB 기본 명령어 참조한다.
추가 : local variable 이외에 해당 클래스의 멤버변수를 확인할 경우 print 또는 p를 사용한다.
(gdb) p 변수명 -> 일반 변수
(gdb) p* 변수명 -> 포인터형 변수(new등)
1.2. 실행중인 프로세스 디버깅
실행중인 프로세스 PID 보기 , ps –ef | grep [프로세스 명]
SKA1PAP1:/>ps -ef | grep ae001serv
muxplt1 28238 1 0 12:00:43 ? 0:00 ae001serv -g 1 -i 200 -u SKA1PAP1 -U muxplt1 6153 6114 0 12:39:04 pts/10 0:00 grep ae001serv
실행중인 프로세스에 attach , gdb [프로세스 명] [pid]
SKA1PAP1:/ >gdb ae001serv 28238
HP gdb 5.8 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
. . .
현재 프로세스의 스택 정보
(gdb) where
#0 0x9fffffffe2e31ad0:0 in _msgrcv_sys+0x30 () from /lib/hpux64/libc.so.1
#1 0x9fffffffe2e41270:0 in msgrcv ()
at ../../../../../core/libs/libc/shared_em_64_perf/../core/syscalls/t_msgrcv.c:19
#2 0x9fffffffe43ccfe0:0 in _tmmbrecvm () at msg/tmmbrecvm.c:364
#3 0x9fffffffe4195a10:0 in _tmmsgrcv () at tmgetrply.c:652