Loo*_*oom 11 c++ debugging windbg crash-dumps visual-c++
我有一个崩溃转储文件(我的32位Windows应用程序已在客户计算机上崩溃).异常代码是0xE06D7363.所以,我在MSDN博客上发现了这篇关于解码异常参数的文章.但是文章中的食谱对我不起作用:
0:000> .exr -1
ExceptionAddress: 753ad36f (KERNELBASE!RaiseException+0x00000058)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 0052ccd8
Parameter[2]: 564099d8
0:000> dd 564099d8 l4
564099d8 00000000 00000000 00000000 564099d0
0:000> dd 564099d0 l2
564099d0 00000001 564099b4
0:000> dd 564099b4 l2
564099b4 00000001 56454aec
0:000> da 56454aec+8
56454af4 "????????????????????????????????"
56454b14 "????????????????????????????????"
56454b34 "????????????????????????????????"
56454b54 "????????????????????????????????"
56454b74 "????????????????????????????????"
56454b94 "????????????????????????????????"
56454bb4 "????????????????????????????????"
56454bd4 "????????????????????????????????"
56454bf4 "????????????????????????????????"
56454c14 "????????????????????????????????"
56454c34 "????????????????????????????????"
56454c54 "????????????????????????????????"
Run Code Online (Sandbox Code Playgroud)
如何使此方法有效?或者可能有其他方法来分析崩溃转储与此异常?
以下是一些信息来自!analyze -v:
PROCESS_NAME: ArcMap.exe
MODULE_NAME: arcmap
FAULTING_MODULE: 76fa0000 ntdll
DEBUG_FLR_IMAGE_TIMESTAMP: 4e793643
ERROR_CODE: (NTSTATUS) 0xe06d7363 - <Unable to get error code text>
EXCEPTION_CODE: (NTSTATUS) 0xe06d7363 - <Unable to get error code text>
EXCEPTION_PARAMETER1: 19930520
EXCEPTION_PARAMETER2: 0052ccd8
EXCEPTION_PARAMETER3: 564099d8
Run Code Online (Sandbox Code Playgroud)
val*_*ldo 13
涉及很多技术细节.我可以给你指路.
第二个异常参数(0052ccd8)是一个指向_s__ThrowInfo结构的指针,它描述了抛出的类型.第三个参数(564099d8)是指向抛出对象的指针.
首先让我们讨论抛出的对象类型.的_s__ThrowInfo点到恒定结构(在编译时生成的),其驻留在可执行(EXE或DLL),这是映射到进程的地址空间内.
如果全局内存包含在崩溃转储中 - 那么您可以在那里找到它.否则,您可以从可执行文件中推断出它.从可执行文件中减去"基本"地址(假设它已在其首选地址加载),您将在可执行文件中获得此结构的偏移量.
从这个结构中解码实际类型是件有点棘手的.它包含有关它可能被转换为的类型的信息(C++多态性),以及d'tor(析构函数),如果它是非平凡类型(具有非平凡的类型)并且它被按值抛出.可以转换类型表以包含指向描述这些类型的适当结构的指针.除此之外还有这些类型的文本"编码".
有关这些结构布局的信息可以在这里找到:
接下来,抛出的对象.它的地址通常属于堆栈内存(严格来说,这不是强制性的,可以抛出全局或动态分配(堆上)对象.但通常情况并非如此).如果崩溃转储中包含堆栈 - 您将看到对象布局.再加上你希望(希望)意识到这意味着它的类型.
如果崩溃转储中没有包含堆栈内存 - 您将无法恢复该对象.
此外,您的对象可能包含指向其他内容(如字符串或其他对象)的成员,这些成员可能不一定在堆栈上分配.除非你有全内存转储,否则很可能你不会意识到这些成员.
老问题和一个很晚的答案(问题在活动列表中弹出,所以回复)
雷蒙德·陈和瓦尔多斯在 consice 脚本中回答的要点
0:000> dt _s_throwinfo pCatchableTypeArray[0]->arrayOfCatchableTypes->pType->name @@c++(( (ntdll!_EXCEPTION_RECORD *) @@masm(@esp+4) )->ExceptionInformation[2])
cppexept!_s_ThrowInfo
+0x00c pCatchableTypeArray : [0]
+0x004 arrayOfCatchableTypes : [0]
+0x004 pType :
+0x008 name : [0] ".PAD"
Run Code Online (Sandbox Code Playgroud)