"Load lock" in C++ mixed mode dll with MFC

G

Guest

Hi,

I wrote a mixed-mode dll (with MFC and C++/CLI) which is called from a C#-EXE.

Under special cirumstances (that is: another process sends a windows-message
to my process - this message is processed by the native part and calls
managed code in turn) a loader lock appears.

I have tracked down the call stack - the interessting part:
- mscorwks.dll (where the exception is raised)
- ... (left out in mscorwks.dll)
- my.dll!InternalDllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!DllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!__DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- my.dll!_DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- mscoree.dll!__CorDllMain@12
... (left out)
- kernel32.dll!ExitThread()

Of course - "my.dll" is my mixed-mode project, but all lines mentioned in
the call-stack are directly from mfc. "InternalDllMain" somehow calls
mscoree.dll with:

AFX_MANAGE_STATE(&afxModuleState); (Line 195 in dllmodul.cpp of mfc)

So, indirectly MFC calls managed-functions from within DllMain. Even more
interessting: The Loader-Lock is reported though DllMain was called for a
"Thread Detach" (dwReason==3), so the loader lock problem should normally not
apply ...

Does anyone know a solution to this?

Thanks in advance!
Jörg Mehlbrech
 
B

Bruno van Dooren [MVP VC++]

I wrote a mixed-mode dll (with MFC and C++/CLI) which is called from a
C#-EXE.

Under special cirumstances (that is: another process sends a
windows-message
to my process - this message is processed by the native part and calls
managed code in turn) a loader lock appears.

I have tracked down the call stack - the interessting part:
- mscorwks.dll (where the exception is raised)
- ... (left out in mscorwks.dll)
- my.dll!InternalDllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!DllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!__DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- my.dll!_DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- mscoree.dll!__CorDllMain@12
... (left out)
- kernel32.dll!ExitThread()

Of course - "my.dll" is my mixed-mode project, but all lines mentioned in
the call-stack are directly from mfc. "InternalDllMain" somehow calls
mscoree.dll with:

AFX_MANAGE_STATE(&afxModuleState); (Line 195 in dllmodul.cpp of mfc)

So, indirectly MFC calls managed-functions from within DllMain. Even
more
interessting: The Loader-Lock is reported though DllMain was called for a
"Thread Detach" (dwReason==3), so the loader lock problem should normally
not
apply ...

I don't have much experience with mixed mode code in dlls, but DllMain is a
very unsafe place to do stuff, regardless of dwReason.
LoaderLocks can happen also during DLL_PROCESS_DETACH or DLL_THREAD_DETACH.

If you do stuff in DllMain, then you should be aware of the following:
http://blogs.msdn.com/mgrier/archive/2005/06.aspx

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
W

William DePalo [MVP VC++]

Joey said:
I wrote a mixed-mode dll (with MFC and C++/CLI) which is called from a
C#-EXE.

Under special cirumstances (that is: another process sends a
windows-message
to my process - this message is processed by the native part and calls
managed code in turn) a loader lock appears.

I have tracked down the call stack - the interessting part:
- mscorwks.dll (where the exception is raised)
- ... (left out in mscorwks.dll)
- my.dll!InternalDllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!DllMain (hInstance, dwReason=3, lpReserved=NULL)
- my.dll!__DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- my.dll!_DllMainCRTStartup (hDllHandle, dwReason=3, lpReserved=NULL)
- mscoree.dll!__CorDllMain@12
... (left out)
- kernel32.dll!ExitThread()

Of course - "my.dll" is my mixed-mode project, but all lines mentioned in
the call-stack are directly from mfc. "InternalDllMain" somehow calls
mscoree.dll with:

Do you have static / global class objects in this DLL? If you do, then they
are initialized during a DLL_PROCESS_ATTACH notification. You get around
that by implementing an initialization function which gets called only AFTER
the DLL is loaded.

Regards,
Will
 
G

Guest

Thank you!

I have only one global variable - as it is required by MFC:
"theApp"
I have a static variable in a managed class (but I think this doesn't bother
anyone..)

The problem I see is different:
With VS2005 Microsoft does not want to support the "/Noentry" option for
mixed mode dlls (_vcclrit.h is deprecated).
--> If a DllMain() exists it will be called for a thread that is being
stopped: Thus if MFC's implementation for DllMain calls mscorwks.dll this
sounds like a bug (or a missing work-around) to me..
In order to the the initialization manually I had to use _vcclrit.h. Did you
mean this method?

Regards,
Joerg Mehlbrech
 
W

William DePalo [MVP VC++]

Joey said:
In order to the the initialization manually I had to use _vcclrit.h. Did
you
mean this method?
Yes.

Thus if MFC's implementation for DllMain calls mscorwks.dll this
sounds like a bug (or a missing work-around) to me..

I do so mixed-mode stuff now and then but MFC only when forced so I can't be
much help here. Sorry.

Regards,
Will
 

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