개요
unix 상에서 프로세스가 cpu 를 과점유하거나 프로세스 hang 과 같은 상황에 빠질 경우 unix OS별로 제공되는 process debugging Utility 를 이용하여 현재 running 중인 Call stack 분석을 통해서
원인을 찾는 데 유용하게 활용할 수 있습니다.
Unix process Debugging 방법들은 Utility마다 틀리고 Unix별로도 조금씩 차이가 나기 때문 에 command가 혼동되는 경우가 많습니다. 간단한 Command위주로 각 Thread Stack을 보는 방법을 설명합니다.
pstack 이용
SUN과 기타 몇개의 Unix, Linux에서 제공하는 Utility로서 Running중인 Process의 Call Stack을 Thread별로 볼수 있는 아주 유용한 Command입니다. DB Hang일때 돌리면 됩 니다.
사용법
- 리눅스
shell> pstack processid
- Sun
shell> pstack -F processid
사용예
dbx 이용
AIX, HP, SUN 에서 제공한다. dbx 명령을 통해서 실행중인 프로세스의 call stack 정보를 확인할 수도 있고 core 파일에서 Thread별 stack 도 확인할 수 있습니다.
AIX상에서 사용하는 방법을 예로 설명합니다.
사용법
- 문제가 있는 procesd의 process id를 확인합니다.
shell> ps -eafl | grep altibase - process 에 attach 합니다.
shell> dbx -a <pid of altibase process> - 모든 thread 정보를 보기
(dbx) thread - 개별적인 thread 정보만 보기
(dbx) thread current < thread number>
(dbx) where detach 하기
(dbx) detach- exit 하기
(dbx) quit
사용예
$ dbx -a 421920
Waiting to attach to process 421920 ...
Successfully attached to altibase.
warning: Directory containing altibase could not be determined.
Apply 'use' command to initialize source path.
Type 'help' for help.
reading symbolic information ...warning: no source compiled with -g
stopped in _event_sleep at 0x9000000004b6a84 ($t6)
0x9000000004b6a84 (_event_sleep+0xe8) e8410028 ld r2,0x28(r1)
(dbx) where
_event_sleep(??, ??, ??, ??, ??, ??) at 0x9000000004b6a84
_event_wait(??, ??) at 0x9000000004b6f5c
_cond_wait_local(??, ??, ??) at 0x9000000004c305c
_cond_wait(??, ??, ??) at 0x9000000004c3628
pthread_cond_timedwait(??, ??, ??) at 0x9000000004c3e38
run()() at 0x100187228
staticRunner(void*)() at 0x10007ea70
(dbx) list
no source file
(dbx) detach
gdb 이용
gdb ( GNU debugger) 가 설치되어 있을 경우 gdb를 활용하여 thread별 stack 정보를 확인할 수 있습니다.
사용법
- gdb 를 대상 process에 attach
shell> $gdb $ALTIBASE_HOME/bin/altibase process-id - 각 thread별 정보 출력
(gdb) info threads - 모든 thread의 stack trace를 출력
(gdb) thread apply all bt - 특정 thread로 switch
(gdb) t 1 : 1번 thread 로 switch - 현재 thread의 stack 출력
(gdb) bt : stack 출력 - 종료
(gdb) quit
사용예
$gdb $ALTIBASE_HOME/bin/altibase 34567
gdb> info threads
42 Thread 31 (LWP 4) 0x329614 in _poll ()
41 Thread 30 0x300cf8 in _lwp_sema_wait ()
40 Thread 29 0x300cf8 in _lwp_sema_wait ()
39 Thread 28 (LWP 29) 0x329614 in _poll ()
38 Thread 27 (LWP 28) 0x329614 in _poll ()
37 Thread 26 (LWP 27) 0x329614 in _poll ()
36 Thread 25 (LWP 26) 0x329614 in _poll ()
5 LWP 28 0x329614 in _poll ()
4 LWP 29 0x329614 in _poll ()
3 LWP 30 0x300cf8 in _lwp_sema_wait ()
* 2 Thread 1 (LWP 1) 0x329614 in _poll ()
1 LWP 1 0x329614 in _poll ()
gdb> thread apply all bt ; 모든 thread의 stack trace를 출력
Thread 2 (Thread 1 (LWP 1)):
#0 0x329614 in _poll ()
#1 0x2f2548 in select_large_fdset ()
#2 0x286908 in __1cKidcManagerGselect6FpnGfd_set_pnOPDL_Time_Value__i_ ()
#3 0x978d8 in __1cMmmtThreadMgrIDispatch6M_nGIDE_RC__ ()
#4 0x945f4 in __1cGmmiMgrIMainLoop6F_nGIDE_RC__ ()
#5 0x929e0 in main ()
Thread 1 (LWP 1 ):
#0 0x329614 in _poll ()
#1 0x2f2548 in select_large_fdset ()
#2 0x286908 in __1cKidcManagerGselect6FpnGfd_set_pnOPDL_Time_Value__i_ ()
#3 0x978d8 in __1cMmmtThreadMgrIDispatch6M_nGIDE_RC__ ()
---Type to continue, or q to quit---
#4 0x945f4 in __1cGmmiMgrIMainLoop6F_nGIDE_RC__ ()
#5 0x929e0 in main ()
#0 0x329614 in _poll ()
gdb> t 1 ; 1번 thread로 switch
gdb> bt ; stack출력
gdb> quit