가정
1. 커널 패닉이 발생하여 덤프 파일이 생성되어 있다
2. 커널
패닉이 발생한 위치가 자신이 빌드한 소스에서 발생하였다
위 두가지 가정하에서 커널 패닉이 유발 시킨 자신의 '코드의 위치'를 찾는
방법에 대하여 소개한다.
커널 덤프 확인
디폴트로 설치된 솔라리스 시스템에서 커널 패닉이 발생하면 덤프
파일이 생성되게 된다.
보통 /var/adm/messege 로그를 보면 최근 발생한 패닉의 정보를 확인 할 수 있는데, messege
파일이
생성되지 않는 경우에서 덤프 파일을 이용하여 패닉 정보를 확인하여야 한다.
덤프 파일이 생성되는 위치는
/var/crash/노드이름/ 하위에 생성되는데, 덤프 파일 이름은 unix.#, vmcore.# 이다.
덤프 파일을 확인 하기 위해서는
adb를 사용하면된다.
shell> adb -k unix.0 vmcore.0
physemem
5b01
0x40027 .....
$<msgbuf <== 타이핑 후
엔터
......
0x300014f5b23: 000002a1007a3b50 unix:die+a4 (31, 2a1007a3e20,
7374616c6c2f636f, 0, ffffffffffffffff, 3720e)
0x300014f5623: %l0-3:
0000000000000000 7374616c6c2f636f 000002a1007a3e20 000002a1007a3d18
%l4-7:
0000000000000031 0000000000002000 0000000000000000
0000000000000000
0x300014f5123: 000002a1007a3c30 unix:trap+874 (2a1007a3e20,
0, 10000, 10200, 7374616c, 2a1007a4024)
0x300014f4c23: %l0-3:
0000000000000001 0000000000000000 00000300066a4a88 0000000000000031
%l4-7:
0000000000000005 0000000000000001 0000000000000000
0000000000000000
0x300014f4723: 000002a1007a3d70 unix:ktl0+48 (0, 2,
ffffffffffffffff, 0, 81010100, ff00)
0x3000154dde3: %l0-3:
0000000000000007 0000000000001400 0000000080001606 000000000102ce88
%l4-7:
000003000000b5b0 000000000144e280 0000000000000000
000002a1007a3e20
0x3000168ce63: 000002a1007a3ec0 test_ke:putMemUse+120 (6d,
2, 3000905bb10, 780ea000, 10, 7374616c6c2f636f) <=== 여기에서 뭔가 잘못된거 같은
느낌...
0x3000168d363: %l0-3: 0000000000078000 000000000000000f
00000300062f9380 000003000000b408
%l4-7: 0000030009323e48 0000000000000000
0000030009323e57 0000000078217d98
0x3000154c123: 000002a1007a3f70
test_ke:retryMalloc+140 (300062f9380, 2, 13aa2d0, 1000, e,
10)
0x3000168dd63: %l0-3: 0000000000000000 0000000000000000
000000000000000f 0000030009323e58
%l4-7: 00000000013ad758 0000000000000020
00000000013ad000 00000000000013ad
0x3000168d5e3: 000002a1007a4040
test_ke:getPathForSymlink+818 (2a1007a52d0, 1, 2a1007a56e0, 2, 2a1007a5ae0,
1)
0x30000438ae3: %l0-3: 0000000000000026 0000000000001395
000003000905bae8 00000000013aa300
%l4-7: 0000000000000026 0000000000000000
0000000000000025 000002a1007a49c1
0x30000438ea3: 000002a1007a4dc0
test_ke:hooked_link_sys32+2d0 (13a05c0, ffbfe78c, 13a0, 13a0000, 0,
300092b61c8)
0x30000439263: %l0-3: 00000000013a01c0 00000000780ea388
0000000000000000 0000000000000000
%l4-7: fffffffffffffffc fffffffffffffffc
000002a1007a4e90 000002a1007a4ed4
0x30000439620:
0x300004399e3: syncing
file systems...
0x30000439da3: 2
0x3000043e1e3: 1
0x3000043e5a3:
done
0x3000043e963: dumping to /dev/dsk/c1t0d0s1, offset 1718288384,
content: kernel
|
위와 같이 패닉 위치를 확인 할 수 있다.
오브젝트 덤프 생성 하기
커널 패닉 위치 감은 잡았지만 적확히 소스의 위치를 확인 하기위해서는 오브젝트 덤프를 생성하여야 한다.
위 패닉
정보에서
'0x3000168ce63: 000002a1007a3ec0 mdp_ke:putMemUse+120 (6d, 2,
3000905bb10, 780ea000, 10, 7374616c6c2f636f)'
패닉의 원인으로 가장 유력해 보이지만 소스의 어느
위치인지 모른다.
솔라리스에서 오브젝트 덤프를 생성하기 위해서는 -fast -xcg92 -S 옵션을 주고 오브젝트 파일을 생성하지 않으면
.s파일이
생성 된다.
shell> cc -D_SOL9_ -D_KERNEL -DSVR4 -DSOL2 -DDEBUG
-D_SYSCALL32 -D_SYSCALL32_IMPL -DSOLARIS_SPARC -m64 -xO5 -xregs=no%appl -v
-fast -xcg92 -S -c module_memchk.c
shell> vi
module_memchk.s
2513 ! 338 !int putMemUse(const char
*pr_fname, long pr_size, char pr_type)
2514
! 339 !{
2515
2516 !
2517 ! SUBROUTINE putMemUse
2518
!
2519 ! OFFSET SOURCE LINE LABEL
INSTRUCTION
2520
2521 .global
putMemUse
2522
2523
2524 putMemUse:
2525 /*
000000 339 */ save %sp,-96,%sp
2526
2527
! 340 ! MEMCHKLIST *find_member = NULL;
2528
! 341 ! int rtv = 0;
2529
! 342 ! char *func = NULL;
2530
! 343 ! int len = strlen(pr_fname);
2531
2532 /*
0x0004 343 */ or %g0,%i0,%o0
2533 /* 0x0008 339 */ sll
%i2,24,%l6
2534 /* 0x000c 343 */ call strlen ! params = %o0 !
Result = %o0
2535 /* 0x0010 339 */ sra %l6,24,%l7
2536
2537
! 345 ! if( pr_fname == NULL )
2538
2539 /* 0x0120 345
*/ cmp %i0,0 <== 여기에서 커널 패닉
발생
2540 /* 0x0018 */ bne .L77001322
2541 /*
0x001c */ nop
|
위와 같이 오브젝트 덤프를 확인 할 수 있다. 덤프 내용을 살펴보면
어셈블과 0x00으로된 주소, 그리고 자신의 코드를 확인
할 수 있다. 앞에서 확인한 커널패닉 로그를 다시
보면
'0x3000168ce63: 000002a1007a3ec0 mdp_ke:putMemUse+120 (6d, 2,
3000905bb10, 780ea000, 10, 7374616c6c2f636f)'
putMemUser함수에서 +120 번째에서 났다는것을
의미 한다.
그러므로 위 코어 더프내용에서 putMemUse 함수를 찾고 그함수 내부에서 0x0120을 찾으면 된다.
|
댓글 없음:
댓글 쓰기