Re: 请教个调试符号的问题。 .reload /i 参数
Windows内核调试
请教个调试符号的问题。 .reload /i 参数
lzh
2007-07-05, 15:23 下午
有时候,在客户的生产环境下没有完全匹配的调试符号,
例如 只是前后编译的时间不同,其实代码没有变化。这种情况下调试符号可以用吗?我问过一个人,他说要严格匹配,否则没有用。真是这样吗,如果这样 .reload 的i 参数还有什么用呢?
还有一个问题
!teb 某线程
!dds StackLimit StackBase
这样能看到很多东西
不明白这些对应什么意义呢。
不像调用堆栈那样好懂
请明白人解释一下,谢谢了!
Re: 请教个调试符号的问题。 .reload /i 参数
格蠹老雷
2007-07-15, 22:51 下午
对于问题1:
一种解决方法是使用/i参数来重新加载缺少符号的程序文件。为了便于发现问题,最好先开启符号加载的“吵杂”模式。
0:000> !sym noisy
noisy mode - symbol prompts on
0:000> .reload /i dbgee.exe
SYMSRV: d:\symbols\dbgee.pdb\75DCAE56ACE24AAE97FDFF4F915565162\dbgee.pdb not found
SYMSRV: http://msdl.microsoft.com/download/symbols/dbgee.pdb/75DCAE56ACE24AAE97FDFF4F915565162/dbgee.pdb not found
DBGHELP: C:\dig\dbg\author\code\chap28\dbgee\Debug\dbgee.pdb - mismatched pdb
DBGHELP: c:\dig\dbg\author\code\chap28\dbgee\Debug\dbgee.pdb - mismatched pdb
DBGHELP: Loaded mismatched pdb for C:\dig\dbg\author\code\chap28\dbgee\Debug\dbgee.exe
*** WARNING: Unable to verify checksum for dbgee.exe
DBGENG: dbgee.exe has mismatched symbols - type ".hh dbgerr003" for details
DBGHELP: dbgee - private symbols & lines
C:\dig\dbg\author\code\chap28\dbgee\Debug\dbgee.pdb - unmatched
以上信息说明,WinDBG尽管发现PDB文件与要求不完全匹配,但是它还是加载了。使用lm命令显示模块列表,也可以看到已经为dbgee模块加载了符号:
0:000> lm
start end module name
00400000 0041a000 dbgee M (private pdb symbols) C:\...\dbgee\Debug\dbgee.pdb
…
其中的M表示符号文件和执行映像文件存在不匹配。
除了使用带有/i开关的.reload命令,也可以通过设置符号选项SYMOPT_LOAD_ANYTHING(0x40)来让调试器加载不严格匹配的符号文件。
0:000> .symopt+0x40
Symbol options are 0x30277:
0x00000001 - SYMOPT_CASE_INSENSITIVE
0x00000002 - SYMOPT_UNDNAME
0x00000004 - SYMOPT_DEFERRED_LOADS
0x00000010 - SYMOPT_LOAD_LINES
0x00000020 - SYMOPT_OMAP_FIND_NEAREST
0x00000040 - SYMOPT_LOAD_ANYTHING
0x00000200 - SYMOPT_FAIL_CRITICAL_ERRORS
0x00010000 - SYMOPT_AUTO_PUBLICS
0x00020000 - SYMOPT_NO_IMAGE_SEARCH
Re: 请教个调试符号的问题。 .reload /i 参数
格蠹老雷
2007-07-15, 23:07 下午
对于第2个问题, DDS命令是用来辅助手工回溯函数调用的, 它的作用就是把指定地址内的每个DWORD当作是函数的返回地址的地址,然后显示出它附近的符号. 因为栈回溯时一个主要目标就是找函数返回地址,然后找函数调用关系. 所以DDS相当于是帮我自动在一段栈数据中寻找函数返回地址。 它的第一个参数通常就指定为当时的栈指针(EIP),即栈顶。例如 0:000> r eax=cccccccc ebx=7ffde000 ecx=00000000 edx=00000001 esi=7c9118f1 edi=0012ff68 eip=004113b4 esp=0012fe9c ebp=0012ff68 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 dbgee!wmain+0x24: 004113b4 c7050000000001000000 mov dword ptr ds:[0],1 ds:0023:00000000=???????? 选取eip的值004113b4 0:000> dds 0012ff68 0012ff68 0012ffb8 0012ff6c 00411966 dbgee!__tmainCRTStartup+0x1b6 [f:\rtm\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 596] 0012ff70 00000001 0012ff74 003a2e90 0012ff78 003a5c20 0012ff7c 2394ef3e 0012ff80 00011970 0012ff84 7c9118f1 ntdll!RtlDeleteCriticalSection+0x72 0012ff88 7ffde000 0012ff8c 00369e99 0012ff90 c0000005 0012ff94 00000000 0012ff98 00130000 0012ff9c 00000000 0012ffa0 0012ff7c 0012ffa4 0012faa0 0012ffa8 0012ffe0 0012ffac 00411082 dbgee!ILT+125(__except_handler4) 0012ffb0 23c77a8e 0012ffb4 00000000 0012ffb8 0012ffc0 0012ffbc 004117ad dbgee!wmainCRTStartup+0x1d 0012ffc0 0012fff0 0012ffc4 7c816ff7 kernel32!BaseProcessStart+0x23 0012ffc8 00011970 0012ffcc 7c9118f1 ntdll!RtlDeleteCriticalSection+0x72 0012ffd0 7ffde000 0012ffd4 c0000005 0012ffd8 0012ffc8 0012ffdc 0012fac0 0012ffe0 ffffffff 0012ffe4 7c839a30 kernel32!_except_handler3 DDS命令自动的显示每个指针值可能对应的符号,除了明显不像的。在这些符号中,我们就可以比较容易的挑选出很像的,组成手工的栈回溯列表: 0012ff6c 00411966 dbgee!__tmainCRTStartup+0x1b6 0012ffbc 004117ad dbgee!wmainCRTStartup+0x1d 0012ffc4 7c816ff7 kernel32!BaseProcessStart+0x23 这和k命令显示的已经有些像: 0:000> k ChildEBP RetAddr 0012ff68 00411966 dbgee!wmain+0x24 [c:\...\dbgee\dbgee.cpp @ 11] 0012ffb8 004117ad dbgee!__tmainCRTStartup+0x1b6 [f:\...\crtexe.c @ 596] 0012ffc0 7c816ff7 dbgee!wmainCRTStartup+0x1d 0012fff0 00000000 kernel32!BaseProcessStart+0x23 后三行是一致的,第一行因为使用了FPO,所以手工方法很难产生。