Killing a thread from an MFC mixed-mode DLL triggers LoadLock MDA

G

Guest

Hi,
I've recently upgraded a mixed-mode MFC DLL of mine from VS2003 to VS2005
using the newer /clr language. In the process I also removed the manual entry
point stuff that used to be necessary.
My problem is that whenever I kill a thread (ie its function exits, and
DllMain gets called with DLL_THREAD_DETACH), I get the LoaderLock MDA kicking
in from line 195 of dllmodul.cpp, which is simply:
AFX_MANAGE_STATE(&afxModuleState);
I can't trace it any deeper than that.
This happens if I kill a thread at any time. Does AFX_MANAGE_STATE step into
managed code? Is it my fault?

Thanks- any help would be appreciated.
 
G

Guest

I've had basically the same problem. I have a more useful call stack though
(I hope you'll forgive me for posting it, but I'll hold off until the end for
it.). Although there are lots of DLLs in this call stack, the error
implicates our mixed-mode DLL specifically. However, all the code that is
running under there belongs to MFC. Therefore, I would like an explanation
from MS as to what is going on. I have traced through this code and the only
guess I have is that they should have coded their DllMain to be #pragma
unmanaged, and did not. But I can't be certain. I actually tried to take
their DllMain (several functions thereof) and incorporate it into mine to
replace theirs, but I got some bizarre errors that I was unable to resolve.
I must just not understand it well enough. After messing around the problem
went away for awhile, and then came back. The only thing that seems to hold
this at bay is simply to turn off the MDA for LoaderLock, which is a very
lame solution.

I want to add that I even wrote code that was supposed to prevent the
DllMain notifications for thread detach, but I still seem to get them (in the
call stack you can see that dwReason=3 which I believe is THREAD_DETACH).
Here's the code I added, right in my InitInstance method:

BOOL C[MixedModeDLL]App::InitInstance()
{
// This should help with Loader Lock problems.
// See:
// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=123858&SiteID=1
// http://blogs.msdn.com/larryosterman/archive/2004/06/03/147736.aspx
// http://blogs.msdn.com/mgrier/archive/2005/06/21/431378.aspx
// http://blogs.msdn.com/cbrumme/archive/2003/08/20/51504.aspx
// The use for it is to prevent DllMain from being invoked when
// threads are created or destroyed, because MFC appears to be a little
// unsafe in handling these cases. Moreover, since we don't do anything
// special with threads, we don't need these notifications (we ignore them).
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DisableThreadLibraryCalls(AfxGetResourceHandle());

return CWinApp::InitInstance();
//return (TRUE);
}

But the net effect is zero. I'm still hosed! I wish I knew why.

Here's the call stack (shortened as much as possible):

[Managed Debug Assistant triggered on Unmanaged Thread]
ntdll.dll!7c90eb94()
[Frames below may be incorrect and/or missing, no symbols loaded for
ntdll.dll]
ntdll.dll!7c90e9c0()
....(kernel32.dll, mscorwks.dll, user32.dll, ntdll.dll)
OUR EXE
....(ntdll.dll, mscorwks.dll)
ONE OF OUR DLLs
OUR EXE
....(ntdll.dll, mscorwks.dll, user32.dll, kernel32.dll, advapi32.dll,
msvcrt.dll)
ONE OF OUR DLLs
....(ntdll.dll, mscorwks.dll, mscoree.dll)
mscoree.dll!79013486()
OUR_MIXED_MODE_DLL.dll!InternalDllMain(HINSTANCE__ * hInstance=0x01600000, unsigned long dwReason=3, void * __formal=0x00000000) Line 195 + 0x5 bytes C++
OUR_MIXED_MODE_DLL!DllMain(HINSTANCE__ * hInstance=0x01600000, unsigned
long dwReason=3, void * lpReserved=0x00000000) Line 276 + 0x11 bytes C++
OUR_MIXED_MODE_DLL!__DllMainCRTStartup(void * hDllHandle=0x01600000,
unsigned long dwReason=3, void * lpreserved=0x00000000) Line 495 + 0x11
bytes C
OUR_MIXED_MODE_DLL!_DllMainCRTStartup(void * hDllHandle=0x01600000,
unsigned long dwReason=3, void * lpreserved=0x00000000) Line 459 + 0x11
bytes C
....(mscoree.dll, ntdll.dll, kernel32.dll)
ONE OF OUR DLLs
....(kernel32.dll)
 
G

Guest

Thanks for the help. Right now I've just given up on the thing. I'm curious
what function exactly it is that steps into managed code. I thought it may be
_AfxInitManaged, but all that seems to do is to work around the EAX bool
return bug that was present in previous versions of the compiler. If I get
any further I'll let you know. I would also appreciate a response from
Microsoft.

Ben
 
G

Guest

I have contacted MS, and it turns out to be a bug in their DllMain
(specifically I think they actually said it is in the AFX_MANAGE_STATE
macro). There is a hotfix available, associated with Knowledge Base article
913996. While this isn't yet published, its URL will be
<a
href="http://support.microsoft.com/?kbid=913996">http://support.microsoft.com/?kbid=913996</a>.
As far as I understand, the hotfix installs on your machine and affects only
DllModul.cpp and MFCS80[d].lib (the import libraries for MFC80[d].dll). So
the good news is, no redistributables are affected. You do need to put it on
all your C++ developer and build machines, though. I have installed the
hotfix and it does appear to solve the problem. At any rate, if you call MS
support, you should be able to get a copy of the hotfix. They did not tell
me whether it was going to be posted publicly soon or not.

One annoyance--I still am not getting calls to my InitInstance() method. I
did a search though and found the answer, at <a
href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=227385&SiteID=1">http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=227385&SiteID=1</a>.
Hope this helps.

--Todd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top