Imagine situation that .NET attempts to release last reference to COM object but due to mismanage on native side, object already destroyed. In our application when native object is destroyed, we fill object with hexadecimal 80. In this case any attempt to release will immediately crash and you will see something like this:
00 000000c6`b97fa430 00007ffa`a13283bd : 00000000`00000000 000001df`76eee2d0 000001df`453f6fd0 00007ffa`a11aee14 : clr!SafeReleasePreemp+0x75
01 000000c6`b97fa4a0 00007ffa`a1328296 : 00000000`05213028 000001df`453f6fd0 000001df`4543af68 00000000`00000000 : clr!RCW::ReleaseAllInterfaces+0xed
02 000000c6`b97fa4f0 00007ffa`a13281ab : 00000000`05213028 000001df`453f6fd0 000000c6`b97fa5c0 00007ffa`41dd4e90 : clr!RCW::ReleaseAllInterfacesCallBack+0x53
03 000000c6`b97fa580 00007ffa`a1391c5e : 000001df`7a47d7b0 000000c6`babffaa8 00007ffa`41cecfa8 00007ffa`d7571a9a : clr!RCW::Cleanup+0x64
Second parameter in SafeReleasePreemp is RCW and you can use !DumpRCW and you will see something like that:
If you work with COM objects you may accidently attempt to use or create COM object in one thread and accidently use it in another thread. And then unless original thread is free threaded .NET will attempt to switch to original thread.
And from there you will see one of the following outcomes.
- If that thread pump messages, then .NET will attempt to send message to that thread to switch. Sometimes it can lead to deadlock or just long delay if that thread is busy. Main thread usually pumps messages, so usually .NET able to switch to main thread.
- You will get error that Interface is not supported. Sometimes you will get that cryptic message even that interface is clearly supported. You will get this message because .NET don’t know how to marshal to original thread, specially if this is some background thread. In this case .NET is not able to marshal, so it will ask object itself to marshal by requesting few interfaces and one of them is IMarshal. Most objects do not support these interfaces and you will see that error message
- When original thread was terminated, or if that was thread pool thread and it will clean its state on next request. In this case you will get this one from MDA: Managed Debugging Assistant 'DisconnectedContext' : 'Transition into COM context 0xed058 for this RuntimeCallableWrapper failed with the following error: The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED)). This is typically because the COM context 0xed058 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else. Releasing the interfaces from the current COM context (COM context 0xec968). This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.'