디버깅을 할때 제일 기본 중 하나가 PDB 관리입니다.
가끔은 PDB를 잃어버리거나 해서 정확한 PDB가 없는 덤프를 분석해야 될 때가 있는데요, 이럴 때, 정확하진 않아도 얼추(?) 비슷한 PDB가 있거나, 아니면 동일한 버젼의 소스코드가 있어서 타임스탬프만 다른 PDB를 만들어낼 수 있다면 아쉬운대로 이 PDB라도 사용해볼 수 있습니다.
1. 먼저 WinDbg에 심볼 경로를 설정해주시고, 해당 경로에 강제로 로딩시키려는 "얼추 비슷한" pdb를 가져다 놓습니다.
0:000> .symfix+ c:\symbols
0:000> .sympath+ c:\symbols
Symbol search path is: c:\symbols;srv*;c:\temp
Expanded Symbol search path is: c:\symbols;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;c:\temp
0:000> .reload
................................................
2. 그러고 나서 해당 모듈의 정보를 살펴보면... PDB가 로딩되지 않았음을 알 수 있습니다. 아마 WinDbg가 타임스탬프가 맞지 않는 "얼추 비슷한" PDB를 거부한 것 같네요.
0:000> lmvm myserver
start end module name
72ff0000 73036000 myserver (export symbols) myserver.dll
Loaded symbol image file: myserver.dll
Image path: C:\Program Files (x86)\myservermain\modules\myserver.dll
Image name: myserver.dll
Timestamp: Wed Jan 09 19:01:13 2013 (50ED3FE9)
CheckSum: 0004A2C9
ImageSize: 00046000
(이하 생략)
콜 스택을 확인해보면 PDB가 로딩되지 않았음을 확인할 수 있습니다.
0:000> kvn
# ChildEBP RetAddr Args to Child
00 0055d2f4 776c8cd8 00000000 00000000 7efde000 ntdll!RtlpWaitOnCriticalSection+0xbd (FPO: [Non-Fpo])
*** ERROR: Symbol file could not be found. Defaulted to export symbols for myserver.dll -
01 0055d31c 730065ba 7302e1cc f12f07aa 021b0a78 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may be wrong.
02 0055d330 72ff3e92 7302e1c8 00000018 00000000 myserver!GetServerCounter+0x91a
03 0055d390 73007e71 00000018 00000000 00000000 myserver+0x3e92
04 0055d3ac 73007c92 00000001 00000000 7302e1f0 myserver!GetServerCounter+0x21d1
05 0055d3c0 73007a08 00000001 7302e1e4 0055d3e0 myserver!GetServerCounter+0x1ff2
06 0055d3d4 730072d4 0055d402 7302e1e4 7302e1e4 myserver!GetServerCounter+0x1d68
07 0055d3ec 7300683e 0055d402 0055d403 7302e1e4 myserver!GetServerCounter+0x1634
08 0055d404 73005f9e 7302e1c8 02415fe8 0055d438 myserver!GetServerCounter+0xb9e
09 0055d618 730064fc f12f02a2 0055d6f4 73024444 myserver!GetServerCounter+0x2fe
0a 0055d630 72ff3e7e 00000000 00000000 7efde000 myserver!GetServerCounter+0x85c
0b 0055d688 72ff7b62 000011a4 f12f0392 00000000 myserver+0x3e7e
*** ERROR: Module load completed but symbols could not be loaded for myservermain.exe
0c 0055d700 00133ca0 f12ca3a2 00000000 00000000 myserver!CreateInstance+0x32
0d 0055d730 00133be9 02303b38 02303b38 0055d780 myservermain+0x3ca0
0e 0055d740 0013391e 00177ea8 00183b60 f12ca312 myservermain+0x3be9
0f 0055d780 00133173 f12c8c96 00000000 00000000 myservermain+0x391e
10 0055f804 0013365a f12c8cbe 00000000 00000000 myservermain+0x3173
11 0055f82c 0013787b 00130000 00000000 001d1a9c myservermain+0x365a
12 0055f8bc 764f339a 7efde000 0055f908 776c9ef2 myservermain+0x787b
13 0055f8c8 776c9ef2 7efde000 53f9b3cc 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
14 0055f908 776c9ec5 001378ce 7efde000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
15 0055f920 00000000 001378ce 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
3. 이때, 다음과 같이 강제로 myserver.dll의 pdb를 로딩해줍니다.
pdb를 강제로 로딩하는 커맨드는 다음과 같습니다.
.reload /i myserver.dll=<모듈이 로딩된 메모리 베이스 주소>,<메모리 상에서의 Image 사이즈>
이 경우엔 다음과 같이 되겠죠.
0:000> lmvm myserver
start end module name
72ff0000 73036000 myserver (export symbols) myserver.dll
Loaded symbol image file: myserver.dll
Image path: C:\Program Files (x86)\myservermain\modules\myserver.dll
Image name: myserver.dll
Timestamp: Wed Jan 09 19:01:13 2013 (50ED3FE9)
CheckSum: 0004A2C9
ImageSize: 00046000
File version: 3.0.0.919
Product version: 3.0.0.1
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
0:000> ? 73036000-72ff0000
Evaluate expression: 286720 = 00046000
0:000> .reload /i myserver.dll=72ff0000,00046000
0:000> lmvm myserver
start end module name
72ff0000 73036000 myserver M (private pdb symbols) C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86\sym\myserver.pdb\50EE61722\myserver.pdb
Loaded symbol image file: myserver.dll
Image path: myserver.dll
Image name: myserver.dll
Timestamp: Wed Jan 09 19:01:13 2013 (50ED3FE9)
CheckSum: 0004A2C9
ImageSize: 00046000
<이하 생략>
짜잔~ 두번째 lmvm 결과를 보면 pdb가 로딩되었음을 알 수 있습니다.
이제 여기서 다시한번 콜스택을 살펴보면... 뭔가 좀더 알아볼 수 있는 결과를 확인할 수 있습니다.
0:000> kvn
# ChildEBP RetAddr Args to Child
00 0055d2f4 776c8cd8 00000000 00000000 7efde000 ntdll!RtlpWaitOnCriticalSection+0xbd (FPO: [Non-Fpo])
01 0055d31c 730065ba 7302e1cc f12f07aa 021b0a78 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])
02 0055d330 72ff3e92 7302e1c8 00000018 00000000 myserver!stlpx_std::vector<stlpx_std::locale::facet *,stlpx_std::allocator<stlpx_std::locale::facet *> >::resize+0x12a (FPO: [Uses EBP] [2,2,4]) (CONV: thiscall) [../../stlport\stl/_vector.h @ 643]
03 0055d390 73007e71 00000018 00000000 00000000 myserver!stlpx_std::priv::_String_base<unsigned short,stlpx_std::allocator<unsigned short> >::_M_allocate_block+0x2 (CONV: thiscall) [d:\[work]\[product]\myservermain\common\include\stlport\stl\_string.c @ 607]
04 0055d3c0 73007a08 00000001 7302e1e4 0055d3e0 myserver!stlpx_std::vector<stlpx_std::locale::facet *,stlpx_std::allocator<stlpx_std::locale::facet *> >::_M_fill_assign+0xb1 (FPO: [2,8,3]) (CONV: thiscall) [../../stlport\stl/_vector.c @ 214]
05 0055d3d4 730072d4 0055d402 7302e1e4 7302e1e4 myserver!stlpx_std::vector<stlpx_std::locale::facet *,stlpx_std::allocator<stlpx_std::locale::facet *> >::_M_insert_overflow_aux+0x198 (CONV: thiscall) [../../stlport\stl/_vector.c @ 101]
06 0055d404 73005f9e 7302e1c8 02415fe8 0055d438 myserver!stlpx_std::vector<stlpx_std::priv::_Slist_node_base *,stlpx_std::allocator<stlpx_std::priv::_Slist_node_base *> >::_M_fill_assign+0x174 (FPO: [2,8,3]) (CONV: thiscall) [../../stlport\stl/_vector.c @ 218]
07 0055d498 776c3c94 776c3cc3 53f99fb0 00000000 myserver!stlpx_std::vector<stlpx_std::locale::facet *,stlpx_std::allocator<stlpx_std::locale::facet *> >::push_back+0x7e (FPO: [Uses EBP] [1,2,4]) (CONV: thiscall) [../../stlport\stl/_vector.h @ 386]
08 0055d574 776c3cee 00002054 00002060 02412a3a ntdll!RtlpAllocateHeap+0xab2 (FPO: [Non-Fpo])
*** ERROR: Symbol file could not be found. Defaulted to export symbols for service.dll -
09 0055d5f8 732e6674 02410000 00000000 00002054 ntdll!RtlAllocateHeap+0x23a (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may be wrong.
0a 0055d618 730064fc f12f02a2 0055d6f4 73024444 service!DeleteInstance+0x5564
0b 0055d688 72ff7b62 000011a4 f12f0392 00000000 myserver!stlpx_std::vector<stlpx_std::locale::facet *,stlpx_std::allocator<stlpx_std::locale::facet *> >::resize+0x6c (FPO: [Uses EBP] [2,2,4]) (CONV: thiscall) [../../stlport\stl/_vector.h @ 643]
0c 0055d700 00133ca0 f12ca3a2 00000000 00000000 myserver!PluginManager::ScheduleThread+0x142 (CONV: stdcall) [D:\[WORK]\[PRODUCT]\myservermain\XMODULE\myserver\PluginManager.cpp @ 400]
0d 0055d730 00133be9 02303b38 02303b38 0055d780 myservermain+0x3ca0
0e 0055d740 0013391e 00177ea8 00183b60 f12ca312 myservermain+0x3be9
0f 0055d780 00133173 f12c8c96 00000000 00000000 myservermain+0x391e
10 0055f804 0013365a f12c8cbe 00000000 00000000 myservermain+0x3173
11 0055f82c 0013787b 00130000 00000000 001d1a9c myservermain+0x365a
12 0055f8bc 764f339a 7efde000 0055f908 776c9ef2 myservermain+0x787b
13 0055f8c8 776c9ef2 7efde000 53f9b3cc 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
14 0055f908 776c9ec5 001378ce 7efde000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
15 0055f920 00000000 001378ce 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
'C++ > Debug' 카테고리의 다른 글
Debugging Tips (13) static loading (implicit loading)된 DLL 강제로 Unload하기 (4) | 2013.06.20 |
---|---|
WinDbg에서 LastErrorCode (GetLastError) 확인하는 법 (0) | 2013.02.14 |
Debugging Tips (11) - 서비스(Service) 디버깅하기 (Vista 이후 OS) (2) | 2012.12.12 |
CodeMachine Debugger Extension DLL (CMKD.dll) (2) | 2012.10.04 |
WinDbg로 커널디버깅 시 "Could not read ObjectType address" 오류 (0) | 2012.05.17 |