|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here. ArchiveDisclaimer|
The LoaderLock managed debugging assistant (MDA) detects attempts to execute managed code on a thread that holds the Microsoft Windows operating system loader lock. Any such execution is illegal because it can lead to deadlocks and to use of DLLs before they have been initialized by the operating system's loader.
The most common failure when executing code inside the operating system's loader lock is that threads will deadlock when attempting to call other Win32 functions that also require the loader lock. Examples of such functions are LoadLibrary, GetProcAddress, FreeLibrary, and GetModuleHandle. The application might not directly call these functions; the common language runtime (CLR) might call these functions as the result of a higher level call likeor the first call to a platform invoke method.
Deadlocks can also occur if a thread is waiting for another thread to start or finish. When a thread starts or finishes executing, it must acquire the operating system's loader lock to deliver events to affected DLLs.
Finally, there are cases where calls into DLLs can occur before those DLLs have been properly initialized by the operating system's loader. Unlike the deadlock failures, which can be diagnosed by examining the stacks of all the threads involved in the deadlock, it is very difficult to diagnose the use of uninitialized DLLs without using this MDA.
Mixed managed/unmanaged C++ assemblies built for .NET Framework versions 1.0 or 1.1 generally attempt to execute managed code inside the loader lock unless special care has been taken, for example, linking with /NOENTRY. For a detailed description of these problems, see "Mixed DLL Loading Problem" in the MSDN .
Mixed managed/unmanaged C++ assemblies built for .NET Framework version 2.0 are less susceptible to these problems, having the same reduced risk as applications using unmanaged DLLs that violate the operating system's rules. For instance, if an unmanaged DLL's DllMain entry point calls CoCreateInstance to obtain a managed object that has been exposed to COM, the result is an attempt to execute managed code inside the loader lock.
Look at the stack trace for the thread that has activated this MDA. The thread is attempting to illegally call into managed code while holding the operating system's loader lock. You will probably see a DLL's DllMain or equivalent entry point on the stack. The operating system's rules for what you can legally do from inside such an entry point are quite limited. These rules preclude any managed execution.
Typically, several threads inside the process will deadlock. One of those threads is likely to be a thread responsible for performing a garbage collection, so this deadlock can have a major impact on the entire process. Furthermore, it will prevent any additional operations that require the operating system's loader lock, like loading and unloading assemblies or DLLs and starting or stopping threads.
In some unusual cases, it is also possible for access violations or similar problems to be triggered in DLLs which are called before they have been initialized.