views:

23

answers:

2

I've the hellish problem of a third party DLL appearing to cause a recursive stack overflow crash when it gets unloaded. I wind up with this pattern on the stack (using 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
...

As you would guess, I don't have the source code to ThirdParty.dll.

Q: What does the prefix "Unloaded_" mean in the stack dump. I haven't run across this before.

+3  A: 

This means that ThirdParty.dll was no longer being referenced and has already been removed from memory at the time that the crash occurs. To find out the actual stack trace, you need to reload the .dll at its original place in memory with the following command:

.reload /f ThirdParty.dll=0xaaaaaaaa

Of course you need to replace 0xaaaaaaaa with the original base address of the module. This may be somewhat hard to figure out if the module has already been unloaded, but if you have an HMODULE lying around that refers to the dll, the value of that HMODULE is the base address. Worst case, you can add a debugger trace statement to your code that logs the HMODULE of the dll just before you unload it.

JSBangs
+1  A: 

I've had a crash just like this before, and as JS points out it means that the dll has been unloaded prior to the crash. However, having the stack trace into that dll may not necessarily give you the information you need to diagnose the problem.

Something in your code is unloading the library because it thinks it's finished with it, but you still have a pointer to it (or to a function inside it) somewhere. My guess would be a callback, perhaps from another thread. I'd suggest searching through your source for any calls to FreeLibrary() and also putting a breakpoint on the FreeLibrary symbol. Find out where the library is being unloaded, and then at that point, ensure that all data that references the dll has been reset. Use a mutex if you have multiple threads.

A tool that may be very useful for this is the excellent Process Monitor which I think shows you dll load and unload events, and will give you a stack trace for each one.

the_mandrill