Friday, March 18, 2005

Deadlock in CLR involving GC & OS Loader lock.

When the Microsoft .NET Framework Execution Engine has to perform garbage collection (GC), the .NET Framework Execution Engine must first suspend all managed threads. In most circumstances, a managed thread must set itself so that it can be suspended before leaving its managed state to run unmanaged code. This thread state is named GC PreEmptable. The GC PreEmptable thread state must be entered by the managed thread before leaving the managed state.In this particular deadlock condition, three different threads are involved as follows:

•Thread 1: This thread is waiting for the Windows NT Loader Lock to complete its task.
•Thread 2: This thread is the owner of the Windows NT Loader Lock. This thread has been suspended by the garbage collection thread. This thread will not release the Windows NT Loader Lock until this thread is restarted by the .NET Framework Execution Engine after the garbage collection is completed. In this case, because the garbage collection is not going to complete, this thread will never release the NT Loader Lock.
•Thread 3: This is the garbage collection thread that is trying to complete garbage collection. To complete the garbage collection, the garbage collection thread has to suspend managed Thread 1 that is waiting for the Windows NT Loader Lock. Because Thread 1 cannot be suspended, the garbage collection is never completed.

This combination of thread conditions leads to a classic deadlock scenario that causes the application to stop responding.

For more information :

The KB article addresses the fix for a specific instance, but there is a generic problem when loading managed C++ dlls that such a condition can occur. This will be fixed only in the Whidbey timeframe. For details: Mixed Dll Loading Problem

The workaround for now (.NET 1.1) will be to preload the managed C++ dlls when a GC is not happening. There is currently no way to disable GC, but you can reduce the probability of GC by forcing a GC and pre-loading the dlls at startup.

No comments: