2015. 3. 25. 16:24

리눅스 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