Skip to content

Deadlock occuring after calling GetTypes() in visual studio #10556

@Snalibe

Description

@Snalibe

First of all, I'm new to this, I'm not even sure I'm posting this at the right place. That being said, here is my problem.

I have a C# application that lazy load a dll. In the constructor of a static class in that dll, I have a call to GetTypes(). The problem seems to occur with a specific timming and only happens when running the application from visual studio. I'm running the .NET Framework 4.7.1.

To be clear:
MyExecutable.exe:
void main() { SomeStaticClass.DoStuff();}

AnotherProject.dll:
static class SomeStaticClass { static SomeStaticClass() { Assembly.GetExecutingAssembly().GetTypes(); } static public void DoStuff() { // Do stuff } }

I've identified 2 threads causing the dead lock.

Thread dotnet/coreclr#1:
This is my application main thread that will eventually call GetTypes() trough one of its dlls.

Thread dotnet/coreclr#2:
It seems to be a thread launched by visual studio:

mscorlib.dll!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssembly LoadedAssembly) Line 3113 C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Reflection.RuntimeAssembly.GetExportedTypes() Line 1482 C# Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.VisualTreeService.GetEnumTypes() Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.VisualTreeService.HandleEnumsRequest(Microsoft.VisualStudio.DesignTools.WpfTap.TapOM.EmptyRequestInfo request) Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.Networking.ProtocolHandler.HandleMessage<Microsoft.VisualStudio.DesignTools.WpfTap.TapOM.EmptyRequestInfo, Microsoft.VisualStudio.DesignTools.WpfTap.TapOM.EnumsResponse>(System.Func<Microsoft.VisualStudio.DesignTools.WpfTap.TapOM.EmptyRequestInfo, Microsoft.VisualStudio.DesignTools.WpfTap.TapOM.EnumsResponse> callback, Microsoft.VisualStudio.DesignTools.WpfTap.Networking.Message requestMessage) Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.Networking.ProtocolHandler.RegisterMessageObserver.AnonymousMethod__0(Microsoft.VisualStudio.DesignTools.WpfTap.Networking.Message message) Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.Networking.ProtocolHandler.OnMessageReceived(byte[] buffer) Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.Networking.ProtocolHandler.ReadThread() Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 954 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 902 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 891 C#
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() Line 111 C#

I went a step further and ran WinDbg and got this:

Thread dotnet/coreclr#1:

ntdll!NtWaitForAlertByThreadId+0x14
ntdll!RtlpWaitOnAddressWithTimeout+0x43
ntdll!RtlpWaitOnAddress+0xb2
ntdll!RtlpWaitOnCriticalSection+0xdb
ntdll!RtlpEnterCriticalSectionContended+0xcc
ntdll!RtlEnterCriticalSection+0x40
clr!CrstBase::SpinEnter+0xac
clr!CrstBase::Enter+0x10d
clr!CrstBase::CrstHolder::CrstHolder+0x14
clr!ClassLoader::LoadTypeHandleForTypeKey_Body+0x819
clr!ClassLoader::LoadTypeHandleForTypeKey+0xee
clr!ClassLoader::LoadTypeDefThrowing+0x227
clr!ClassLoader::LoadTypeDefOrRefThrowing+0x279
clr!GetTypesInner+0x216
clr!COMModule::GetTypes+0xba
mscorlib_ni!System.Reflection.Assembly.GetTypes()$##600421C+0x70
0x00007ffc`5d0a3204
clr!CallDescrWorkerInternal+0x83
clr!CallDescrWorkerWithHandler+0x4e
clr!DispatchCallDebuggerWrapper+0x1f

Thread dotnet/coreclr#2:

ntdll!NtWaitForAlertByThreadId+0x14
ntdll!RtlpWaitOnAddressWithTimeout+0x43
ntdll!RtlpWaitOnAddress+0xb2
ntdll!RtlpWaitOnCriticalSection+0xdb
ntdll!RtlpEnterCriticalSectionContended+0xcc
ntdll!RtlEnterCriticalSection+0x40
clr!CrstBase::SpinEnter+0xac
clr!CrstBase::Enter+0x10d
clr!ListLockEntry::LockHolder::DeadlockAwareAcquire+0x4b
clr!MethodTable::DoRunClassInitThrowing+0x1be
clr!MethodTable::CheckRunClassInitThrowing+0xa3
clr!MethodDesc::DoPrestub+0xdd8
clr!PreStubWorker+0x3cc
clr!ThePreStub+0x55
mscorlib_ni!System.AppDomain.OnAssemblyLoadEvent(System.Reflection.RuntimeAssembly)$##6000815+0x3f
clr!CallDescrWorkerInternal+0x83
clr!CallDescrWorkerWithHandler+0x4e
clr!MethodDescCallSite::CallTargetWorker+0xf8
clr!AppDomain::RaiseLoadingAssemblyEvent+0xffffffff`fffe1534
clr!DomainAssembly::DeliverAsyncEvents+0x40

I have a work around for now, I simply construct my static class very soon the the application, but I'm wondering if it's a known issue or if I'm doing something wrong.

Again, the application works fine when not running it with visual studio.

Visual Studio Professional 2017
Version 15.6.1

.Net Framework
Version 4.7.02558

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions