Loader lock error

90.7k Views Asked by At

I am building on C++ dll, by writing code in C#.

I get an error, saying

LoaderLock was detected Message: Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.

I tried seraching what this error exactly means, but I am drawing pointless articles, mostly saying that it's just a warning, and I should switch that off in Visual Studio. The other solutions seem to be due to ITunes, or this problem occurring when programming with DirectX. My problem is connected to neither.

Can anybody explain, what this actually means?

9

There are 9 best solutions below

2
On

kindly remind those VS2017 users that you need to disable "exception helper" instead of "exception assistant"(before VS2017) to prevent from loader lock error, which setting path is Debug->Exception. Just ran int to this problem and wasted 2 hours searching for solutions...

0
On

This problem occurs because of the way in which the debugger in Visual Studio runs managed applications that use Microsoft Foundation Classes version 8.0 in one or more DLL files.

Have a thorough reading at: http://msdn.microsoft.com/en-us/library/aa290048(vs.71).aspx

1
On

Press ctr d+e Then Expend Managed Debugging Assistants Node. Then Unchecked the LoaderLock.

Hope this will help you.

1
On

I recently got this error while creating an instance of an COM-Object written in native code:

m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));

This led to the described error. A "LoaderLock was detected"-Exception was thrown.

I overcame this error by creating the object-instance in an extra thread:

ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
Thread myThread = new Thread(threadRef);

myThread.Start();
myThread.Join(); // for synchronization
0
On

The setting path in my visual studio 2017 instance is Debug -> Windows -> Exception Settings . The exception settings "window" showed up in the bottom tab group (as opposed to a separate window), took me a while to notice it. Search for "loader".

6
On

you need to go to menu Debug -> Exceptions, open the Managed Debugging Assistants, find LoaderLock and uncheck

http://goo.gl/TGAHV

0
On

I'm building a C++ CLR DLL (MSVS2015) that has to make calls into an unmanaged DLL and define unmanaged code. I use #pragma managed and #pragma unmanaged to control what mode it is in for a given area of the code.

In my case I simply put #pragma unmanaged in front of my DllMain() and this solved the problem. It seemed to be thinking I wanted a managed version of DllMain().

0
On

UPDATE FOR .NET 4.0 AND MORE RECENT FRAMEWORKS

This is an old question asked at the time of .Net 2.0, when support for mixed mode DLLs had serious initialization problems, prone to random deadlocks. As of .Net 4.0, the initialization of mixed mode DLLs has changed. Now there are two separate stages of initialization:

  1. Native initialization, called at the DLL's entry point, which includes native C++ run-time setup and execution of your DllMain method.
  2. Managed initialization, executed automatically by system loader.

Since step #2 is performed outside of the Loader Lock, there is no deadlocks. The details are described at Initialization of Mixed Assemblies.

To ensure your mixed mode assembly can be loaded from a native executable, the only thing you need to check is that DllMain method is declared as native code. #pragma unmanaged could help here:

#pragma unmanaged

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    ... // your implementation here
}

It is also important that any code that DllMain might call directly or indirectly is also unmanaged. It makes sense to limit the type of functionality used by DllMain so you trace all code reachable from DllMain and ensure it is all compiled with #pragma unmanaged.

Compiler helps a little by giving you warining C4747 if it detects that DllMain is not declared as unmanaged:

1>  Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint

However compiler won't generate any warnings if DllMain indirectly calls some other managed function, so you need to ensure that never happens, otherwise your application could deadlock randomly.

1
On

The general idea of loader lock: The system runs the code in DllMain inside a lock (as in - synchronization lock). Therefore, running non-trivial code inside DllMain is "asking for a deadlock", as described here.

The question is, why are you trying to run code inside DllMain? Is it crucial that this code run inside the context of DllMain or can you spawn a new thread and run the code in it, and not wait for the code to finish execution inside DllMain?

I believe that the problem with manged code specifically, is that running managed code might involves loading the CLR and suchlike and there's no knowing what could happen there that would result in a deadlock... I would not heed the advice of "disable this warning" if I were you because most chances are you'll find your applications hangs unexpectedly under some scenarios.