“已卸载”前缀在Windows堆栈跟踪中的含义是什么?

时间:2010-06-28 15:09:56

标签: windows

我遇到了第三方DLL的一个地狱般的问题,当它被卸载时会出现导致递归堆栈溢出崩溃的问题。我最终将这个模式放在堆栈上(使用windbg):

<Unloaded_ThirdParty.dll>+0xdd01
ntdll!ExecuteHandler2+0x26
ntdll!ExecuteHandler+0x24
ntdll!KiUserExceptionDispatcher+0xf
<Unloaded_ThirdParty.dll>+0xdd01
ntdll!ExecuteHandler2+0x26
ntdll!ExecuteHandler+0x24
ntdll!KiUserExceptionDispatcher+0xf
...

正如您猜测的那样,我没有ThirdParty.dll的源代码。

问:堆栈转储中的前缀“Unloaded_”是什么意思。我之前没有碰过这个。

2 个答案:

答案 0 :(得分:8)

这意味着ThirdParty.dll不再被引用,并且在崩溃发生时已从内存中删除。要找出实际的堆栈跟踪,您需要使用以下命令将.dll重新加载到内存中的原始位置:

.reload /f ThirdParty.dll=0xaaaaaaaa

当然,您需要将0xaaaaaaaa替换为模块的原始基址。这可能有点难以确定模块是否已经卸载,但如果你有一个HMODULE位于dll引用,那么HMODULE的值就是基地址。最糟糕的情况是,您可以在代码中添加一个调试器跟踪语句,在您卸载它之前记录该组的HMODULE

答案 1 :(得分:1)

我之前遇到过这样的崩溃,正如JS指出的那样意味着dll在崩溃之前已被卸载。但是,将堆栈跟踪到该dll可能不一定会为您提供诊断问题所需的信息。

代码中的某些东西正在卸载库,因为它认为它已经完成了,但你仍然有一个指向它的指针(或它内部的一个函数)。我的猜测是回调,也许来自另一个线程。我建议在您的来源中搜索对FreeLibrary()的任何调用,并在FreeLibrary符号上添加断点。找出卸载库的位置,然后确保已重置引用该dll的所有数据。如果您有多个线程,请使用互斥锁。

一个可能对此非常有用的工具是优秀的Process Monitor,我认为它会显示你将加载和卸载事件,并为每个事件提供一个堆栈跟踪。