Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Allocate handles for custom marshalers in ALCs instead of in the AppDomain. #25105

Merged
merged 1 commit into from
Jun 12, 2019

Conversation

jkoritzinsky
Copy link
Member

Fixes #25100

@jkoritzinsky jkoritzinsky added this to the 3.0 milestone Jun 11, 2019
Copy link
Member

@janvorli janvorli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@jkoritzinsky
Copy link
Member Author

Looks like the pending checks are finished on AzDO and the timeout is from Helix queue length being too long. I'm going to merge this in.

@jkoritzinsky jkoritzinsky merged commit a8b4c8f into dotnet:master Jun 12, 2019
@jkoritzinsky jkoritzinsky deleted the allocate-cm-in-la branch June 12, 2019 17:16
@janvorli
Copy link
Member

@jkoritzinsky I've just ran this inside of a collectible AssemblyLoadContext and it doesn't work correctly. It crashes during LoaderAllocator shutdown, as you can see below. The problem is that at the point where it is trying to free the handle, the LoaderAllocator's handle table and in fact the managed LoaderAllocator that keeps that table is long gone.
Removing the call to FreeHandle from CustomMarshalerInfo::~CustomMarshalerInfo() fixes the crash, however I am not sure if the native LoaderAllocator shutdown is the only code path that calls this destructor.

 # Child-SP          RetAddr           Call Site
00 00000040`1a77dc00 00007ff8`31f8415e CoreCLR!Object::GetGCSafeMethodTable+0x2b [F:\git\coreclr\src\vm\object.h @ 471] 
01 00000040`1a77dc30 00007ff8`31f83f07 CoreCLR!Object::ValidateInner+0x9e [F:\git\coreclr\src\vm\object.cpp @ 593] 
02 00000040`1a77de80 00007ff8`31f7b71c CoreCLR!Object::Validate+0x157 [F:\git\coreclr\src\vm\object.cpp @ 573] 
03 00000040`1a77df00 00007ff8`31b07dbb CoreCLR!OBJECTREF::OBJECTREF+0xdc [F:\git\coreclr\src\vm\object.cpp @ 1264] 
04 00000040`1a77df70 00007ff8`31fe53bd CoreCLR!ObjectFromHandle+0x5b [F:\git\coreclr\src\vm\gchandleutilities.h @ 45] 
05 00000040`1a77dfc0 00007ff8`31fd8f1b CoreCLR!LoaderAllocator::SetHandleValue+0x3cd [F:\git\coreclr\src\vm\loaderallocator.cpp @ 985] 
06 00000040`1a77e2e0 00007ff8`3221414a CoreCLR!LoaderAllocator::FreeHandle+0x2bb [F:\git\coreclr\src\vm\loaderallocator.cpp @ 881] 
07 00000040`1a77e4b0 00007ff8`32224b8c CoreCLR!CustomMarshalerInfo::~CustomMarshalerInfo+0x4a [F:\git\coreclr\src\vm\custommarshalerinfo.cpp @ 139] 
08 00000040`1a77e4f0 00007ff8`32221acc CoreCLR!CustomMarshalerInfo::`scalar deleting destructor'+0x2c
09 00000040`1a77e520 00007ff8`31fd074c CoreCLR!EEMarshalingData::~EEMarshalingData+0x7c [F:\git\coreclr\src\vm\mlinfo.cpp @ 1108] 
0a 00000040`1a77e5b0 00007ff8`31fd6fa2 CoreCLR!EEMarshalingData::`scalar deleting destructor'+0x2c
0b 00000040`1a77e5e0 00007ff8`31fe5b12 CoreCLR!LoaderAllocator::DeleteMarshalingData+0x1d2 [F:\git\coreclr\src\vm\loaderallocator.cpp @ 1654] 
0c 00000040`1a77e720 00007ff8`31fce698 CoreCLR!LoaderAllocator::Terminate+0x1f2 [F:\git\coreclr\src\vm\loaderallocator.cpp @ 1318] 
0d 00000040`1a77e990 00007ff8`31fce38b CoreCLR!LoaderAllocator::~LoaderAllocator+0x258 [F:\git\coreclr\src\vm\loaderallocator.cpp @ 96] 
0e 00000040`1a77eb50 00007ff8`31fd06ec CoreCLR!AssemblyLoaderAllocator::~AssemblyLoaderAllocator+0x11b [F:\git\coreclr\src\vm\loaderallocator.cpp @ 1715] 
0f 00000040`1a77ebb0 00007ff8`31eb026d CoreCLR!AssemblyLoaderAllocator::`scalar deleting destructor'+0x2c
10 00000040`1a77ebe0 00007ff8`31cd7f9b CoreCLR!SystemDomain::ProcessDelayedUnloadLoaderAllocators+0x3cd [F:\git\coreclr\src\vm\appdomain.cpp @ 6283] 
11 00000040`1a77eda0 00007ff8`31f1a0e5 CoreCLR!Thread::DoExtraWorkForFinalizer+0x22b [F:\git\coreclr\src\vm\threads.cpp @ 7338] 
12 00000040`1a77eed0 00007ff8`31ce414a CoreCLR!FinalizerThread::FinalizerThreadWorker+0x1f5 [F:\git\coreclr\src\vm\finalizerthread.cpp @ 342] 
13 00000040`1a77ef40 00007ff8`31ce41fa CoreCLR!ManagedThreadBase_DispatchInner+0x1aa [F:\git\coreclr\src\vm\threads.cpp @ 7410] 
14 00000040`1a77f070 00007ff8`31ce8ed5 CoreCLR!ManagedThreadBase_DispatchMiddle+0x8a [F:\git\coreclr\src\vm\threads.cpp @ 7454] 
15 00000040`1a77f380 00007ff8`31ce9334 CoreCLR!``ManagedThreadBase_DispatchOuter'::`11'::__Body::Run'::`5'::__Body::Run+0x65 [F:\git\coreclr\src\vm\threads.cpp @ 7620] 
16 00000040`1a77f3f0 00007ff8`31ce4341 CoreCLR!`ManagedThreadBase_DispatchOuter'::`11'::__Body::Run+0x94 [F:\git\coreclr\src\vm\threads.cpp @ 7620] 
17 00000040`1a77f4a0 00007ff8`31ce471b CoreCLR!ManagedThreadBase_DispatchOuter+0x111 [F:\git\coreclr\src\vm\threads.cpp @ 7642] 
18 00000040`1a77f5b0 00007ff8`31cd9bad CoreCLR!ManagedThreadBase_NoADTransition+0x1cb [F:\git\coreclr\src\vm\threads.cpp @ 7690] 
19 00000040`1a77f700 00007ff8`31f1a487 CoreCLR!ManagedThreadBase::FinalizerBase+0x2d [F:\git\coreclr\src\vm\threads.cpp @ 7717] 
1a 00000040`1a77f730 00007ff8`31f19b1c CoreCLR!`FinalizerThread::FinalizerThreadStart'::`39'::__Body::Run+0x97 [F:\git\coreclr\src\vm\finalizerthread.cpp @ 416] 
1b 00000040`1a77f7a0 00007ff8`31cf20aa CoreCLR!FinalizerThread::FinalizerThreadStart+0x1bc [F:\git\coreclr\src\vm\finalizerthread.cpp @ 430] 
1c 00000040`1a77f870 00007ff8`a40b7bd4 CoreCLR!Thread::intermediateThreadProc+0xea [F:\git\coreclr\src\vm\threads.cpp @ 2061] 
1d 00000040`1a77f970 00007ff8`a4fcce71 KERNEL32!BaseThreadInitThunk+0x14 
1e 00000040`1a77f9a0 00000000`00000000 ntdll!RtlUserThreadStart+0x21  

@jkoritzinsky
Copy link
Member Author

It looks like there's one path that the destructor isn't called from within LoaderAllocator shutdown. When there's a race between multiple threads to create the same custom marshaler info, only one is kept and the others are released.

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make Custom Marshalers unloadability-friendly
2 participants