디버깅을 할때 제일 기본 중 하나가 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])


Posted by kuaaan

댓글을 달아 주세요



사랑합니다. 편안히 잠드소서