windbg调试实例(3)——崩溃蓝屏之内核堆栈溢出
1、崩溃发生背景
一个系统内核驱动程序运行过程中导致蓝屏。
2、提取dump文件
a) Dump可用前提:崩溃存储为核心内存存储,该项设置在:系统属性–高级–启动和故障恢复–设置–写入调试信息
b) 找到系统windows目录下memory.dmp
3、分析蓝屏原因
1)windbg打开dump
2)!analyze -v 分析挂掉线程的详细情形,错误原因。
[code]01 0: kd> !analyze -v
02 UNEXPECTED_KERNEL_MODE_TRAP (7f)
03 This means a trap occurred in kernel mode, and it's a trap of a kind
04 that the kernel isn't allowed to have/catch (bound trap) or that
05 is always instant death (double fault). The first number in the
06 bugcheck params is the number of the trap (8 = double fault, etc)
07 Consult an Intel x86 family manual to learn more about what these
08 traps are. Here is a *portion* of those codes:
09 If kv shows a taskGate
10 use .tss on the part before the colon, then kv.
11 Else if kv shows a trapframe
12 use .trap on that value
13 Else
14 .trap on the appropriate frame will show where the trap was taken
15 (on x86, this will be the ebp that goes with the procedure KiTrap)
16 Endif
17 kb will then show the corrected stack.
18 Arguments:
19 Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
20 Arg2: 80148000
21 Arg3: 00000000
22 Arg4: 00000000
[/code]
UNEXPECTED_KERNEL_MODE_TRAP (7f)表示这个问题发生在内核模式。一个线程的内核栈只有12K大小,在栈的末端有一页无效的页面进行保护。当使用的栈大小超过12K,访问到那个无效页面的时候,处理器就会触发一个页错误,然后试图把寄存器压入栈中,结果造成了第二个页错误。这就是double fault的含义。这里可以猜测这个内核驱动程序访问了12k以外的内存。
因为!analyze -v显示的堆栈信息不完全,所以要加个数字比如100 来完全显示,同时用f需要显示栈上每个部分使用了多少字节:
[code]01 0: kd> kf 100
02 24 951e5f84 84d7ea91 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x22a
03 4c 951e5fd0 81827ecf fltmgr!FltpCreate+0x2a1
04 18 951e5fe8 8c383125 nt!IofCallDriver+0x63
05 c 951e5ff4 8c385142 Lanman+0x1125
06 aa4 951e6a98 8c384eca Lanman+0x3142
07 20 951e6ab8 8c3839ac Lanman+0x2eca
08 10 951e6ac8 81827ecf Lanman+0x19ac
09 18 951e6ae0 81996f5c nt!IofCallDriver+0x63
10 b8 951e6b98 819eef0d nt!IopParseDevice+0xcff
11 90 951e6c28 819ec6b9 nt!ObpLookupObjectName+0x615
12 60 951e6c88 819839e0 nt!ObOpenObjectByName+0x13c
13 74 951e6cfc 819833ca nt!IopCreateFile+0x5ec
14 5c 951e6d58 84d85516 nt!IoCreateFileEx+0x9d
15 98 951e6df0 84d85891 fltmgr!FltpExpandFilePathWorker+0x162
16 18 951e6e08 84d85ada fltmgr!FltpExpandFilePath+0x19
17 1c 951e6e24 84d86129 fltmgr!FltpGetNormalizedFileNameWorker+0x160
18 18 951e6e3c 84d8351f fltmgr!FltpGetNormalizedFileName+0x19
19 18 951e6e54 84d6eb71 fltmgr!FltpCreateFileNameInformation+0x81
20 20 951e6e74 84d6ecbe fltmgr!HandleStreamListNotSupported+0x125
21 30 951e6ea4 84d6f37c fltmgr!FltpGetFileNameInformation+0xc6
22 28 951e6ecc 8c396a8a fltmgr!FltGetFileNameInformation+0x120
23 3c 951e6f08 84d69843 PROCMON12+0x2a8a
24 5c 951e6f64 84d6bf10 fltmgr!FltpPerformPreCallbacks+0x2e5
25 14 951e6f78 84d7e292 fltmgr!FltpPassThroughInternal+0x32
26 14 951e6f8c 84d7ea7f fltmgr!FltpCreateInternal+0x24
27 44 951e6fd0 81827ecf fltmgr!FltpCreate+0x28f
28 18 951e6fe8 8c383125 nt!IofCallDriver+0x63
29 c 951e6ff4 8c385142 Lanman+0x1125
30 aa4 951e7a98 8c384eca Lanman+0x3142
31 20 951e7ab8 8c3839ac Lanman+0x2eca
32 10 951e7ac8 81827ecf Lanman+0x19ac
33 18 951e7ae0 81996f5c nt!IofCallDriver+0x63
34 b8 951e7b98 819eef0d nt!IopParseDevice+0xcff
35 90 951e7c28 819ec6b9 nt!ObpLookupObjectName+0x615
36 60 951e7c88 819839e0 nt!ObOpenObjectByName+0x13c
37 74 951e7cfc 819900f5 nt!IopCreateFile+0x5ec
38 48 951e7d44 8188c96a nt!NtOpenFile+0x2a
39 0 951e7d44 77020f34 nt!KiFastCallEntry+0x12a
40 0006f7c0 00000000 0x77020f34
[/code]
看一下两处红色标示,使用字节很大并且都来自lanman这个程序,达到5448byte,这就已经接近12k的一半了,所以后面猜测是耗尽、溢出了。再此开发也应该知道问题在哪里了,使用这12k内存不小心,所以开发人员须注意尽量不要在栈上分配超过1K的内存,不能递替调用,但是如果调用太深的话,还是会溢出的,这个就要遇到看怎么解决了.
实例二
1、程序崩溃发生过程
这是一个对文件进行处理的模块,而处理模块在处理之前,需查询被处理的文件是否值得处理。这个任务执
行过程中发生了崩溃,问题就发生在查询模块。
2、提取dump文件
3、分析dump:
1)启动windbg,file–open crash dump 配置符号库,reload完成 。
2)使用命令 :.ecxr获得进程崩溃时寄存器的内容
[code]1 0:021> .ecxr (意指恢复崩溃时所有寄存器的内容,包括堆栈等)
2 eax=0532d414 ebx=00000fec ecx=000003fb edx=00000000 esi=0532c428 edi=00000000
3 eip=750f53ea esp=0490f22c ebp=0490f234 iopl=0 nv up ei pl nz na pe nc
4 cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
5 msvcr80!memmove+0x5a:
6 750f53ea f3a5 rep movs dword ptr es:[edi],dword ptr [esi] es:002b:00000000=???????? ds:002b:0532c428=00000000
[/code]
3)使用命令:k 显示堆栈
[code]01 0:021> k (.ecxr不能直接显示堆栈,需使用k显示堆栈)
02 *** Stack trace for last set context - .thread/.cxr resets it
03 ChildEBP RetAddr
04 WARNING: Stack unwind information not available. Following frames may be wrong.
05 0490f234 03ba4806 msvcr80!memmove+0x5a(kxewfsys调用memmove,memmove是个字符串操作函数,能把字符串的一部分复制到另一部分,这里出问题,可能是复制时传递的指针有问题,或者字符串的大小有问题)
06 0490f25c 03ba2547 kxewfsys!__ovfl_get+0xa6 (调用memmove之前内部的一些处理)
07 0490f27c 03ba4a74 kxewfsys!__bt_cmp+0x77
08 0490f2a8 03ba2679 kxewfsys!__bt_search+0x74
09 0490f2c4 03ba1409 kxewfsys!__bt_get+0x49
10 0490f2d8 03ba7448 kxewfsys!IKBDBImpl::Get+0x19
11 0490f2f8 03ba750d kxewfsys!CFdbFileInfo::Search+0x28 [e:\eingsoft_euba\build\build_src\kice\kice_kxewhite\src\kxewfssys\fdbfileinfo.cpp @ 483]
12 0490f338 03ba9c63 kxewfsys!CFdbFileInfo::QueryFileInfo+0x4d [e:\eingsoft_euba\build\build_src\kice\kice_kxewhite\src\kxewfssys\fdbfileinfo.cpp @ 546]
13 0490f380 028210d1 kxewfsys!CFdbManager::QueryFileInfo+0xa3 [e:\eingsoft_euba\build\build_src\kice\kice_kxewhite\src\kxewfssys\fdbmanager.cpp @ 370] (kxewfsys 是处理查询模块)
14 *** ERROR: Symbol file could not be found. Defaulted to export symbols for kspfeng.dll
15 0490f390 03b1323c kxewhite!kxe_white_query_file_info+0x21 [e:\eingsoft_euba\build\build_src\kice\kice_kxewhite\src\kxewfssdk\kxewfs.cpp @ 103] (将文件提交进行查询.)
16 0490f45c 03b13442 kspfeng!KSEGetAddonEntries+0x21fbc (kspfeng.dll是文件处理模块用到的公共功能的封装文件)
17 *** ERROR: Symbol file could not be found. Defaulted to export symbols for ksecore.dll
18 0490f498 03abcaa4 kspfeng!KSEGetAddonEntries+0x221c2
19 0490f4c8 03b07fd5 ksecore+0x1caa4
20 0490f52c 03b1c52b kspfeng!KSEGetAddonEntries+0x16d55
21 0490f860 5019dd7c kspfeng!KSEGetAddonEntries+0x2b2ab
22 0490f864 01c95695 0x5019dd7c
23 0490f868 1a77217c 0x1c95695
24 0490f86c 01c95693 0x1a77217c
25 0490f870 1a7982dc 0x1c95693
26 0490f874 01c95693 0x1a7982dc
[/code]
4、总结崩溃原因
查询模块,对文件路径的处理存在bug。
实例1
这个系列的文章是vivilisa写的,但是前几天去他的博客看貌似没有这几篇文章了,原来把这系列文章存在
了电脑里,现在拿出来跟大家分享,不知道vivilisa是不是同意。暂时先发表了再说,不成的话就了。感觉他写
的这几篇调试文章很好,称赞下。
1、崩溃发生过程 程序执行过程中崩溃,弹出mssagebox,提示R6034错误。查看r6034错误:表示运行库的
manifest设置不正确。