I have a large C++/CLI application, which hosts 3rd-party binaries also written in C++/CLI. Sometime I get crashes on shutdown, with exception code c0020001(*). I know it means some CLI method is getting called after CLI was already shutdown.
Question: How can I find out which managed method was trying to get called? I found out in some cases (Stack trace 1 below), but not for others (Stack trace 2 below).
What I tried
I captured full dumps of some such crashes, and the dumps show 2 different stacks traces (below).
- Stack trace 1 has
clr!UMThunkStubRareDisableWorkerin it, and since it matches this windbg guide I was able to find out the managed method it was trying to call. - Stack trace 2 has different frame
clr!TheUMEntryPrestubWorker, which inside callsclr!CanRunManagedCode. The above guide couldn't help me with this.
Stack trace 1
00 00000000`2e09e520 00007ff8`712659bf KERNELBASE!RaiseException+0x69
01 00000000`2e09e600 00007ff8`70cd22e8 clr!UMThunkStubRareDisableWorker+0x3f
02 00000000`2e09e630 00007fff`ff20e4dc clr!UMThunkStub+0x128
03 00000000`2e09e6c0 00007ff8`831bcf13 The3rdParty+0xe4dc
04 00000000`2e09e700 00007ff8`83130752 combase!<lambda_ef8a5b5bdab9c6b69f38e6b21c5d3987>::operator()+0xbb [onecore\com\combase\dcomrem\stdid.cxx @ 1409]
05 00000000`2e09e740 00007ff8`831307f5 combase!ObjectMethodExceptionHandlingAction<<lambda_ef8a5b5bdab9c6b69f38e6b21c5d3987> >+0xe [onecore\com\combase\dcomrem\excepn.hxx @ 128]
06 00000000`2e09e790 00007ff8`831bca36 combase!CStdIdentity::ReleaseCtrlUnk+0x81 [onecore\com\combase\dcomrem\stdid.cxx @ 1412]
(...additional combase and rpcrt4 frames...)
Stack trace 2
00 00000000`000cf500 00007ff8`71265833 KERNELBASE!RaiseException+0x69
01 00000000`000cf5e0 00007ff8`70cd217e clr!TheUMEntryPrestubWorker+0x43
02 00000000`000cf630 00007fff`fdcd47a4 clr!TheUMEntryPrestub+0x3e
03 00000000`000cf6a0 00007fff`fe07cc74 the3rdparty+0x47a4
04 00000000`000cf6d0 00007ff8`828d42d6 the3rdparty!DllUnregisterServer+0x11b694
05 00000000`000cf700 00007ff8`828d41fb ucrtbase!<lambda_f03950bc5685219e0bcd2087efbe011e>::operator()+0xa6
06 00000000`000cf750 00007ff8`828d41b4 ucrtbase!__crt_seh_guarded_call<int>::operator()<<lambda_7777bce6b2f8c936911f934f8298dc43>,<lambda_f03950bc5685219e0bcd2087efbe011e> &,<lambda_3883c3dff614d5e0c5f61bb1ac94921c> >+0x3b
07 00000000`000cf780 00007fff`fdf7f475 ucrtbase!execute_onexit_table+0x34
08 00000000`000cf7b0 00007fff`fdf7f59a the3rdparty!DllUnregisterServer+0x1de95
09 00000000`000cf7f0 00007ff8`7248ae44 the3rdparty!DllUnregisterServer+0x1dfba
0a 00000000`000cf850 00007ff8`755c1bad mscoreei!CorDllMain+0x1b4
0b 00000000`000cf8d0 00007ff8`755c1c07 mscoree!ShellShim__CorDllMain+0xf5
0c 00000000`000cf910 00007ff8`85089a1d mscoree!CorDllMain_Exported+0x37
0d 00000000`000cf940 00007ff8`850cdcda ntdll!LdrpCallInitRoutine+0x61
0e 00000000`000cf9b0 00007ff8`850cda8d ntdll!LdrShutdownProcess+0x22a
0f 00000000`000cfac0 00007ff8`8479e3bb ntdll!RtlExitUserProcess+0xad
10 00000000`000cfaf0 00007ff8`72471cd5 kernel32!ExitProcessImplementation+0xb
Guide for Stack Trace 1
Based on this windbg guide
0:036> k
# Child-SP RetAddr Call Site
00 00000000`2e09e520 00007ff8`712659bf KERNELBASE!RaiseException+0x69
01 00000000`2e09e600 00007ff8`70cd22e8 clr!UMThunkStubRareDisableWorker+0x3f
02 00000000`2e09e630 00007fff`ff20e4dc clr!UMThunkStub+0x128
(...)
0:036> .loadby sos clr <<<<<<< Only worked for me on the repro machine - needs to have exact same build of CLR?
0:036> .sympath+ srv* ; .cordll -ve -u -l <<< Seems to load everything
0:036> u clr!UMThunkStub L50
clr!UMThunkStub:
(...)
00007ff8`70cd22d9 4c895548 mov qword ptr [rbp+48h],r10 <<<<<<<<<<< Storing r10, which has the method desc of the callback)
00007ff8`70cd22dd 498bcc mov rcx,r12
00007ff8`70cd22e0 498bd2 mov rdx,r10
00007ff8`70cd22e3 e898365900 call clr!UMThunkStubRareDisableWorker (00007ff8`71265980)
00007ff8`70cd22e8 4c8b5548 mov r10,qword ptr [rbp+48h] <<<<<<<<<<< RetAddr in stack
0:036> !dumpmd poi(poi(@rbp+48)+0x8) <<<<<< Taking r10 from [@rbp+48], the look at internal data structure with details of where the method desc resides.
Method Name: <Module>.ATL.CComObject<The3rdParty::ClassINeedToUninit>.__vecDelDtor(ATL.CComObject<The3rdParty::ClassINeedToUninit>*, UInt32)
Class: 00007ff812089678
MethodTable: 00007ff8120947b0
mdToken: 000000000600007e
Module: 00007ff812075010
IsJitted: yes
CodeAddr: 00007ff811f7b920
Transparency: Safe critical
(*) c0020001 is ERROR_INVALID_FUNCTION - Incorrect function, although is sometimes incorrectly interpreted as RPC_NT_INVALID_STRING_BINDING - The string binding is invalid.