솔라리스를 사용하다보면 간혹 홈 디렉토리에 코어(core)화일이 생기는 것을 볼 수가 있습니다. 사용에 별 지장이 없다면 그냥 지나쳐도 상관없겠지만, 그 코어가 내가 운영하는 서비스와 관련이 있는 지도 모르므로 확인해보는 습관은 중요합니다.


대개 메모리 접근 위반(Segmentation Violation)으로 생성되는 것이 대부분인데, 솔라리스의 애플리케이션에 포인터 처리가 미숙했거나, 솔라리스가 허용하는 데이타 패싱이 아니었거나 솔라리스에서 허용하는 프로토타입과 상이하게 다르거나 하는 경우에 흔히 생깁니다.

일단 core 화일이 생기게 되면, 해당 애플리케이션의 current directory에 생성됩니다. 대게 많은 애플리케이션들이 홈에서 시작이 되므로, 혹은 홈으로 현재 디렉토리를 옮기게 되므로 홈 디렉토리에 core가 왕왕 생기는 것을 볼 수가 있습니다. 또한, 솔라리스 내장되어 있는 각종 패키지들(gnome)과 같은 데스크 탑 솔루션등도 시작할때 홈에서 시작하므로 버그가 있는 경우 홈에서 core를 많이 볼 수가 있습니다.

core가 생기면 어떤 화일이 어디에서 문제가 생겨서 죽었는 지를 다음과 같이 해서 알 수 있습니다.

#file core
core: ELF 32-bit MSB core file SPARC Version 1, from 'thunderbird-bin'

#pstack core

core 'core' of 3968: /opt/sfw/lib/thunderbird/thunderbird-bin
----------------- lwp# 1 / thread# 1 --------------------
ff3416e0 _lwp_kill (b, ffbfe4b0, 0, b, fc00, 1) + 8
0051086c ???????? (b, 0, 510748, 510400, a, c4)
ff340618 __sighndlr (b, 0, ffbfe620, 510784, 0, 1) + c
ff335710 call_user_handler (b, ffbffeff, 0, 0, fe2b2000, ffbfe620) + 3b8
010b4794 ???????? (6e6e800, ff0a49bc, 24002400, 28002800, 28002800, 6e6e800)
010b5b44 ???????? (6cf5090, 63636c8, ff000000, 0, 80000000, ff0a39e4)
ff0a6fc0 __1cYnsOutputStreamReadyEventMEventHandler6FpnHPLEvent__pv_ (6c6fa74,
6c6faa8, 6c6fa70, 6cf5090, 10b5ab8, 18d79a0) + 34
ff0c03a0 PL_HandleEvent (6c6fa74, 1985454, ff0a6f8c, 1985454, 1985450, 6c6fa74) + 14
ff0c02b8 PL_ProcessPendingEvents (12, 1, d, 0, 0, 1985450) + 7c
ff0c23cc __1cQnsEventQdDueueImplUProcessPendingEvents6M_I_ (196dd08, 80004000,
ff000000, 0, 0, 1aef090) + 20
0072b840 ???????? (1af2f38, 1, 196dd08, 1, 1, ff0c23ac)
fea55ac8 g_main_dispatch (196e898, feabec00, 0, 0, fffffffd, ffffffef) + 19c
fea56ffc g_main_context_dispatch (196e898, c8, 0, 1, feabec00, 196e898) + 9c
fea574c8 g_main_context_iterate (1, 1, 1, 196e898, 196e8a0, 9) + 454
fea57c44 g_main_loop_run (1b99fe0, feabec00, ff339c58, 199a2f8, feaaa800, feaaa800) + 348
fee2a424 gtk_main (0, 0, 1b99fe0, 1aa4500, feff1eb0, 4ce0) + d0
0072bba4 ???????? (1aa6ac8, 196dd08, 18332d4, 72bbc0, c1f30000, 0)
....

위의 core는 thunderbird-bin이 생성한 것임을 알 수가 있습니다.
위의 core는 불행하게도 두가지 문제가 있는데, 하나는 debugging symbol을 가지고 있지 않는 함수가 있다는 것이고, 하나는 C++에 의한 맹글링으로 인해 함수 이름을 알아보기 어렵다는 점이 있습니다.

일단, C++ mangling 문제는 다음과 같이 함으로써 해결할 수 있습니다.

$pstack core | /opt/SUNWspro/bin/c++filt | less
core 'core' of 3968: /opt/sfw/lib/thunderbird/thunderbird-bin
----------------- lwp# 1 / thread# 1 --------------------
ff3416e0 _lwp_kill (b, ffbfe4b0, 0, b, fc00, 1) + 8
0051086c ???????? (b, 0, 510748, 510400, a, c4)
ff340618 __sighndlr (b, 0, ffbfe620, 510784, 0, 1) + c
ff335710 call_user_handler (b, ffbffeff, 0, 0, fe2b2000, ffbfe620) + 3b8
010b4794 ???????? (6e6e800, ff0a49bc, 24002400, 28002800, 28002800, 6e6e800)
010b5b44 ???????? (6cf5090, 63636c8, ff000000, 0, 80000000, ff0a39e4)
ff0a6fc0 void*nsOutputStreamReadyEvent::EventHandler(PLEvent*) (6c6fa74, 6c6faa8, 6c6fa70, 6cf5090, 10b5ab8, 18d79a0) + 34
ff0c03a0 PL_HandleEvent (6c6fa74, 1985454, ff0a6f8c, 1985454, 1985450, 6c6fa74) + 14
ff0c02b8 PL_ProcessPendingEvents (12, 1, d, 0, 0, 1985450) + 7c
ff0c23cc unsigned nsEventQueueImpl::ProcessPendingEvents() (196dd08, 80004000,
ff000000, 0, 0, 1aef090) + 20
0072b840 ???????? (1af2f38, 1, 196dd08, 1, 1, ff0c23ac)
fea55ac8 g_main_dispatch (196e898, feabec00, 0, 0, fffffffd, ffffffef) + 19c
fea56ffc g_main_context_dispatch (196e898, c8, 0, 1, feabec00, 196e898) + 9c
fea574c8 g_main_context_iterate (1, 1, 1, 196e898, 196e8a0, 9) + 454
fea57c44 g_main_loop_run (1b99fe0, feabec00, ff339c58, 199a2f8, feaaa800, feaaa800) + 348
fee2a424 gtk_main (0, 0, 1b99fe0, 1aa4500, feff1eb0, 4ce0) + d0
0072bba4 ???????? (1aa6ac8, 196dd08, 18332d4, 72bbc0, c1f30000, 0)
....

c++filt는 썬 스튜디오를 설치하면 따라오는 유틸리티입니다.
기본적으로 /usr/ccs/bin/nm도 디맹글링을 지원합니다만 사용 환경이 다릅니다.

위에서 발생한 core는 thunderbird-bin이 링크하는 동적 라이브러리에서 출력 스트림 이벤트 핸들러에서 발생한 문제임을 알수가 있습니다. 어느 라이브러리에서 발생했는지 알기 위해서는 커널 디버거인 mdb를 사용해야 합니다.

> mdb core
Loading modules: [ libc.so.1 libuutil.so.1 ld.so.1 ]
> $C
ffbfe3f0 libc.so.1`_lwp_kill+8(b, ffbfe4b0, 0, b, fc00, 1)
ffbfe450 0x51086c(b, 0, 510748, 510400, a, c4)
ffbfe4c0 libc.so.1`__sighndlr+0xc(b, 0, ffbfe620, 510784, 0, 1)
ffbfe520 libc.so.1`call_user_handler+0x3b8(b, ffbffeff, 0, 0, fe2b2000, ffbfe620)
ffbfe8d8 0x10b4794(6e6e800, ff0a49bc, 24002400, 28002800, 28002800, 6e6e800)
ffbfe940 0x10b5b44(6cf5090, 63636c8, ff000000, 0, 80000000, ff0a39e4)
ffbfe9a8
libxpcom_core.so`__1cYnsOutputStreamReadyEventMEventHandler6FpnHPLEvent__pv_+0x34(6c6fa74, 6c6faa8, 6c6fa70, 6cf5090, 10b5ab8, 18d79a0)
ffbfea08 libxpcom_core.so`PL_HandleEvent+0x14(6c6fa74, 1985454, ff0a6f8c,
1985454, 1985450, 6c6fa74)
ffbfea68 libxpcom_core.so`PL_ProcessPendingEvents+0x7c(12, 1, d, 0, 0, 1985450)
ffbfeac8 libxpcom_core.so`__1cQnsEventQdDueueImplUProcessPendingEvents6M_I_+0x20(196dd08, 80004000, ff000000, 0, 0, 1aef090)
ffbfeb30 0x72b840(1af2f38, 1, 196dd08, 1, 1, ff0c23ac)
ffbfeb90 libglib-2.0.so.0.400.1`g_main_dispatch+0x19c(196e898, feabec00, 0, 0,
fffffffd, ffffffef)
ffbfebf8 libglib-2.0.so.0.400.1`g_main_context_dispatch+0x9c(196e898, c8, 0, 1,
feabec00, 196e898)

....

위에서 $C 명령어는 core가 유도된 스레드의 스택을 보여줍니다.
장애의 소스가 되는 관심있는 함수와 모듈을 알수 있습니다.
libxpcom_core.so를 확인하게 되면 앞서 보았던, void*nsOutputStreamReadyEvent::EventHandler(PLEvent*)
임을 알 수 있기 때문입니다. 따라서, 개발자들은 이 함수의 소스를 확인해야 합니다.

지금부터는 이 함수의 어느 부분이 문제인지 확인하기 위해서는 소스 디버거나 dtrace를 사용해야만 하겠죠.

그러나, 경험적으로 core의 몇가지 정보를 더 얻을 수 있다면, 문제가 무엇인지 직감하는데 도움이
되는 경우도 있습니다.

예를 들면, 해당 core가 어떤 크리덴셜(퍼미션)을 가지고 실행했는가 ?
해당 코어는 어떤 환경에서 실행되었는가등을 알면 매우 큰 도움이 되는 경우가 있습니다.
다음과 같은 유틸리티를 통해서 알수가 있습니다.

#pargs -e core
#pldd core
#pcred core

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Posted by 소리나는연탄.

Leave your greetings here.