티스토리 뷰

Framework/ProFrame

[ProFrame C] core 분석

Reo Dongmin Lee 2018. 10. 29. 14:36

dbx는 Unix 소스 레벨 debugger다. 

프로프레임에서 발생하는 core는 dbx를 이용하여 분석이 가능하다.

dbx로 core 분석법을 알아보기 위해 일단 core를 발생시킬 소스를 만들어서 컴파일 한다.

dbx를 사용하기 위해서는 컴파일 옵션으로 -g를 넣어줘야 하는데 프로프레임 make 파일에 기본적으로 -g 옵션을 사용하고 있다.

다음은 프로프레임 서비스 모듈에 코어를 발생시킬 소스를 추가한 것이다.



일단 core를 분석하기 위해서 core가 어떤 프로그램에서 발생했는지 알아본다.

일반적으로 core 파일은 core를 발생시킨 바이너리와 동일한 폴더에 생성되지만 프로프레임은 보통 $PFM_CORE_DIR/{코어발생날짜}/{코어발생모듈} 폴더에 core 파일을 생성한다.

file 명령어를 사용하면 core 가 발생한 프로그램 바이너리와 bit 수를 출력해준다.

pfm5c@tmax:/pfm5c/proframe/logging/core/20181026/STEST00004]file core
core: AIX core file 64-bit, TPFM01

dbx 명령어로 프로그램 바이너리 경로와 core 파일을 실행한다.

위의 코어는 티맥스 tcs 서버에서 호출한 서비스 모듈에서 발생한 core 이므로 서버 바이너리 경로는 $TMAXDIR/appbin 밑에 있는 서버 바이너리를 넣어준다.

ex> dbx [바이너리경로] [코어파일명]

pfm5c@tmax:/pfm5c/proframe/logging/core/20181026/STEST00004]dbx $TMAXDIR/appbin/TPFM01 core
도움말을 보려면 'help'를 입력하십시오.
경고: 코어 파일이 전체 코어(fullcore)가 아닙니다. 일부 정보가
사용 가능하지 않을 수 있습니다.
[core에서 메모리 이미지 사용]
기호 정보를 읽는 중 ...

Segmentation fault in pfmKillSelfProcess at line 1056 in file ""
"pfmOsWrapper.c"을(를) 읽을 수 없습니다.
(dbx)

dbx는 많은 명령어와 다양한 분석기법 사용이 가능하지만 가장 간단하고 흔히 쓰는 명령어는 where 명령어다. where 명령어로 function call stack을 읽어서 어떤 파일의 어떤 function이 호출될 때 core가 발생했는지 확인이 가능하다.

(dbx) where
pfmKillSelfProcess(signal = 1224736768), line 1056 in "pfmOsWrapper.c"
pfmSigExit(sigNum = 1224736768, action = 648535941234377828), line 427 in "pfmSigHdl.c"
pfmSignalHandler_all(sigNum = 0), line 247 in "pfmSigHdl.c"
.() at 0xfe04
unnamed block in b100_input_check(context = 0x0fffffffffff87f0), line 188 in "stest00004.c"
b100_input_check(context = 0x0fffffffffff87f0), line 188 in "stest00004.c"
unnamed block in stest00004(input = 0x09000000107a2748, output = (nil)), line 66 in "stest00004.c"
stest00004(input = 0x09000000107a2748, output = (nil)), line 66 in "stest00004.c"
_tdlcall() at 0x900000010e67fec
tdlcall2s() at 0x900000010e6ae90
_pfmDlCall2S(libname = 경고: 코어로부터 주소 0x8001000a0ba2934에 액세스할 수 없습니다.
(invalid char ptr (0x08001000a0ba2934)), fname = 경고: 코어로부터 주소 0x8001000a0ba2cd8에 액세스할 수 없습니다.
(invalid char ptr (0x08001000a0ba2cd8)), input = 0x00000000000000c4, output = 0x4400000000000044, file_name = 경고: 코어로부터 주소 0x8001000a0ba27d4에 액세스할 수 없습니다.
(invalid char ptr (0x08001000a0ba27d4)), func_name = 경고: 코어로부터 주소 0x1102f541d에 액세스할 수 없습니다.
(invalid char ptr (0x00000001102f541d)), line = 4563672960), line 355 in "pfmDlCall.c"
unnamed block in pfmServiceMainProcessing(pfmServiceContext = 0x09000000000055a4), line 240 in "pfmServiceFrame.c"
pfmServiceMainProcessing(pfmServiceContext = 0x09000000000055a4), line 240 in "pfmServiceFrame.c"
_tdlcall() at 0x900000010e67fa0
tdlcall2() at 0x900000010e6b264
_pfmDlCall2(libname = 경고: 코어로부터 주소 0x9001000a15a7dbc에 액세스할 수 없습니다.
(invalid char ptr (0x09001000a15a7dbc)), fname = 경고: 코어로부터 주소 0x9001000a15a7754에 액세스할 수 없습니다.
(invalid char ptr (0x09001000a15a7754)), args = 0x00000000000002fd, file_name = 경고: 코어로부터 주소 0x4400000000000044에 액세스할 수 없습니다.
(invalid char ptr (0x4400000000000044)), func_name = 경고: 코어로부터 주소 0x9001000a15a73e8에 액세스할 수 없습니다.
(invalid char ptr (0x09001000a15a73e8)), line = 4566467376), line 239 in "pfmDlCall.c"
unnamed block in pfmFlowControlFrame.pfmCallServiceFlow(ctx = 0x0000000000000054, flow_cfg = 0x0000000000000001, type = 268435455, startSecitNumbr = 7380607468296417139, errorSectionSubFlowNumber = 0x09000000107a2acc), line 768 in "pfmFlowControlFrame.c"
pfmFlowControlFrame.pfmCallServiceFlow(ctx = 0x0000000000000054, flow_cfg = 0x0000000000000001, type = 268435455, startSecitNumbr = 7380607468296417139, errorSectionSubFlowNumber = 0x09000000107a2acc), line 768 in "pfmFlowControlFrame.c"
unnamed block in pfmServiceFrameMainProcessing(ctx = 0x0fffffffffffc1f8, flow_cfg = 0x0000000000000054), line 246 in "pfmFlowControlFrame.c"
pfmServiceFrameMainProcessing(ctx = 0x0fffffffffffc1f8, flow_cfg = 0x0000000000000054), line 246 in "pfmFlowControlFrame.c"
STEST00004(msg = 0x000000000000de42), line 139 in "TPFM01.c"
_call_svc_func() at 0x900000010e13474
_run_svc() at 0x900000010e13028
_request_from_clh() at 0x900000010e16768
_loop() at 0x900000010e15ba4
_tmax_main() at 0x900000010e16954
TPFM01_svctab.main(argc = 0, argv = (nil)), line 43 in "TPFM01_svctab.c"
(dbx)

위 처럼 stest00004 서비스 모듈의 188번째 라인에서 코어가 발생하였음을 확인할 수 있다.

AIX에서 dbx 의 더 자세한 사용법은 다음의 링크를 참고한다.


댓글