天天看点

windbg .exepath命令:windbg调试kernel dump时需要指定image-path

    这些天,调试张银奎<硬错误和蓝屏:分析系统转储文件>一章节的dump文件Mini121206-01.dmp时,书中P375写到

"

kd> lm m real*
start    end    module name
xxxx     xxxx   RealBug      T...      

其中T代表这个模块的时间戳信息缺失,这是因为windbg还未能加载到这个模块的映像文件

kd> k
ChildEBP RetAddr
...
Unable to load image RealBug.sys, Win32 error2      

以上信息说明windbg因为未能找到RealBug文件并因此未能加载符号文件

当作者设置映像文件路径并再次执行.reload后,再次执行lm,RealBug模块后的T标志消失,再次执行k命令,没有任何警告和错误信息。"

    这段话让我很不理解,首先,以前我做live调试时,看到最多的是(export symbol)和(defered)这样的模块状态,几乎没有注意到符号状态是类似"T/C/#"标示。其次,live调试时只要设置符号路径(通过.sympath命令)即可,从未设置过映像路径(通过.exepath命令)。最后,最疑惑的一点,如果调试内核时需要额外指定image-path,那像nt/hal这类内核OS本身的模块,我从未指定过他们的映像路径,就能加载调试符号/下断点等;唯独RealBug这个第三方驱动因为没有指定image-path而不能加载符号,难道有某些机制提供了映像文件?

    为了验证作者的这个说法,我打开dump文件,运行kv命令后的确有"Unable to load image Realbug.sys"这样的错误消息。开始时我怀疑是不是符号路径写的不对,于是多次检查我的RealBug的调试路径,确定路径没有问题后,多次.reload依旧失败:

(以下命令为调试符号路径:)

kd> .symfix C:\sym\xpsp1_free_2600 ;C:\sym\xpsp1_free_2600是本地缓存调试符号路径
kd> .sympath
Symbol search path is: srv*
Expanded Symbol search path is: SRV*C:\sym\xpsp1_free_2600*https://msdl.microsoft.com/download/symbols

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*
kd> .sympath+ C:\Users\Eugen\Desktop\dump ;C:\Users\Eugen\Desktop\dump是<软件调试>书中dump文件夹的路径 里面包含了pdb/sys等文件
Symbol search path is: srv*;C:\Users\Eugen\Desktop\dump
Expanded Symbol search path is: SRV*C:\sym\xpsp1_free_2600*https://msdl.microsoft.com/download/symbols;c:\users\eugen\desktop\dump      

(截图是dump文件夹里的文件:)

windbg .exepath命令:windbg调试kernel dump时需要指定image-path

(以下命令为执行.reload/lm的结果:)

kd> lm m realbug
Browse full module list
start    end        module name
fa18b000 fa18bd00   RealBug    (deferred)             
kd> ld realbug
*** WARNING: Unable to verify timestamp for RealBug.SYS
Symbols loaded for RealBug
kd> lm m realbug
Browse full module list
start    end        module name
fa18b000 fa18bd00   RealBug  M (private pdb symbols)  c:\users\eugen\desktop\dump\RealBug.pdb      

第一次执行lm时,显示RealBug模块延迟加载;执行ld强制加载模块后再次执行lm,虽然windbg显示了RealBug.pdb调试符号的路径,但在符号状态栏里,有个M标示。对于这个标示windbg帮助文档解释为:

摘自MS debug Symbol Status Abbreviations章节:

"M : There is a mismatch between the symbol file and the executable, either in their timestamps or in their checksums. However, symbol files have been loaded anyway due to the symbol option settings."

在这种情况下执行k命令显示调用堆栈,会得到警告信息,如下:

kd> k
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 f6869b20 804dac8f nt+0x526bf
01 f6869b2c 00000000 nt+0x6c8f      

从windbg的输出来看,好像又是符号不对,只能再次加载符号试试能不能解决问题:

kd> .reload
Loading Kernel Symbols
...............................................................
...............................
Loading User Symbols
Loading unloaded module list
............
kd> k
 # ChildEBP RetAddr  
00 f6869ac0 80607339 nt!KeBugCheck+0x10
01 f6869b20 804dac8f nt!Ki386CheckDivideByZeroTrap+0x23
02 f6869b20 fa18b4e1 nt!KiTrap00+0x6d
Unable to load image RealBug.SYS, Win32 error 0n2
*** WARNING: Unable to verify timestamp for RealBug.SYS


kd> lm m realbug
Browse full module list
start    end        module name
fa18b000 fa18bd00   RealBug  M (private pdb symbols)  c:\users\eugen\desktop\dump\RealBug.pdb      

这就是前面我说的,不加载image文件,调试dump文件时一直会报错...最后,我决定按图索骥:

kd> .exepath C:\Users\Eugen\Desktop\dump
Executable image search path is: C:\Users\Eugen\Desktop\dump
Expanded Executable image search path is: c:\users\eugen\desktop\dump

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
OK                                             C:\Users\Eugen\Desktop\dump
kd> .reload
Loading Kernel Symbols
...............................................................
...............................
Loading User Symbols
Loading unloaded module list
............
kd> lm m realbug
Browse full module list
start    end        module name
fa18b000 fa18bd00   RealBug    (deferred) ;设置image path后            
kd> ld realbug
Symbols loaded for RealBug
kd> lm m realbug
Browse full module list
start    end        module name
fa18b000 fa18bd00   RealBug    (private pdb symbols)  c:\users\eugen\desktop\dump\realbug.pdb
kd> k
 # ChildEBP RetAddr  
00 f6869ac0 80607339 nt!KeBugCheck+0x10
01 f6869b20 804dac8f nt!Ki386CheckDivideByZeroTrap+0x23
02 f6869b20 fa18b4e1 nt!KiTrap00+0x6d
03 f6869bcc fa18b54b RealBug!PropDivideZero+0x3f [c:\dig\training\advdbg\dbglabs\realbug\realbug.c @ 63]
04 f6869bdc fa18b62e RealBug!DivideZero+0xb [c:\dig\training\advdbg\dbglabs\realbug\realbug.c @ 77]
05 f6869be8 fa18b73e RealBug!RealBugDeviceControl+0x44 [c:\dig\training\advdbg\dbglabs\realbug\realbug.c @ 114]
06 f6869c34 804eca36 RealBug!RealBugDispatch+0x8e [c:\dig\training\advdbg\dbglabs\realbug\realbug.c @ 175]
07 f6869c44 8058b076 nt!IopfCallDriver+0x31
08 f6869c58 8058bc62 nt!IopSynchronousServiceTail+0x5e
09 f6869d00 805987ec nt!IopXxxControlFile+0x5ec
0a f6869d34 804da140 nt!NtDeviceIoControlFile+0x28
0b f6869d34 7ffe0304 nt!KiSystemService+0xc4
0c 0012f8a8 00000000 SharedUserData!SystemCallStub+0x4      

解释一下.exepath是用来指定image文件路径,和.sympath类似的用法。加载image后在运行.reload重载符号一切正常。后来我查了很多资料,在stackover上发现有很多国外网友也问道类似问题,网友回复时有提到:live调试不需要指定image path;而调试dump文件时需要指定image path,因为解析pdb文件中的内容需要依赖于image文件中的信息。这就解释了我的第二个疑惑:为什么live调试不需要指定image path,唯独调试dump文件需要指定image path。很简单,当进行live调试时,kernel模块的image文件就在系统中,可以帮助windbg解析对应pdb文件;然后解析dump文件时,运行windbg的系统和产生dump文件的系统极有可能不一致,进一步说dump文件中记录的模块和调试dump文件的系统中的模块不一致,致使windbg无法根据dump文件中记录的exepath来定位image path进而解析pdb中的调试信息。

    目前前两个问题都顺理解答了,还有第三个问题:从调试服务器上除了下载到pdb文件还会意外的获得nt/hal等模块的映像?根据我的观察,调试dump文件时,虽然指定了sympath,但windbg在下载符号时,确实会连同把nt/hal等image文件一起下载到sympath指定的缓存目录中。等到下载结束缓存目录中除了有nt.pdb本身,还有nt.exe文件。因此调试dump文件时,虽然没有指定内核image文件的路径(甚至可能我根本没法提供内核image文件),windbg还是有办法定位这些文件并解析相应pdb文件的内容。然而,像Realbug这种第三方驱动,必然不会存在于MS的调试符号器上,windbg自然无法下载Realbug.sys文件并解析pdb文件的内容,因此会导致提示符号加载状态不正确/堆栈回溯有错误信息等一系列问题。