I believe I have found a bug in CLR 2.0 (System.Runtime.InteropServices)

J

johnxhc

I have the big application, it has C#, VB.NET, VB6 & VC++ components,
those components calling each other, passing the objects between the
managed & unmanaged layer.


The application crashes in one operation scenario, the crash is caused
by the following:
1) A COM (ComComp1 ,written with VB6.0) component is marshaled
to .NET (NetComp1)
2) NetComp1 create a instance of another Comp Component (ComComp2,
written with VC++6.0) and store it as a variable
3) Then ComComp1 is marshaled back to COM component(ComComp2)
4) This ComComp1 component is stored in a map (class member) in
ComComp2, the map is defined as following :
typedef map<_bstr_t,_variant_t> PropertyMap;
The COMComp1 is store in the second element of the map as _variant_t

Under certain circumstances. When the Gabage.Collect is called,
NetComp1 is collected, then the Destructor for COM Component
(COMComp2) is called, all the memory in its map is freed, since the
map has the _variant_t in it, the VariantClear is called, but for
whatever reason, the object (COMComp1) stored in the _variant_t is
invalid (has been released), causing a Access Violation.

If I store a COM Component in a _variant_t, an should Addref() is
called and that object should never be released, so I do not
understand why sometimes the COMComp1 is invalid, how could the
COMComp1 be release if other object still hold is as a reference.
Please advice.
Thanks in advance.
The stack trace is as following, the error happen in the following
line :
0012d35c 12d715d4 AppContainer!_variant_t::~_variant_t+0x29




0:000> kL 200
ChildEBP RetAddr
0012cf58 7c90e96c ntdll!KiFastSystemCallRet
0012cf5c 7c91e7d3 ntdll!NtUnmapViewOfSection+0xc
0012d04c 7c80abf7 ntdll!LdrUnloadDll+0x31a
0012d060 77513442 kernel32!FreeLibrary+0x3f
0012d06c 77513456 ole32!
CClassCache::CDllPathEntry::CFinishObject::Finish+0x2f
0012d080 775135fe ole32!CClassCache::CFinishComposite::Finish+0x1d
0012d228 77513578 ole32!CClassCache::FreeUnused+0x19d
0012d238 775133a2 ole32!CoFreeUnusedLibrariesEx+0x36
0012d244 6605a01e ole32!CoFreeUnusedLibraries+0x9
0012d258 6605b4d1 MSVBVM60!CCreDestroyCtlStruct+0x387
0012d27c 6601c56a MSVBVM60!CCreDestroyCtl+0x195
0012d2c0 6601bc56 MSVBVM60!CCreFUnloadForm+0x1c9
0012d2cc 660c9ed5 MSVBVM60!CUnkDesk::Release+0x23
0012d2e4 6600e720 MSVBVM60!BASIC_CLASS::pRIVATE_UNKNOWN::Release+0x11c
0012d2ec 77124918 MSVBVM60!SCM_MsoStdCompMgr::Release+0xd
0012d300 12d75f49 OLEAUT32!VariantClear+0xb1
0012d35c 12d715d4 AppContainer!_variant_t::~_variant_t+0x29
0012d3c0 12d74b25 AppContainer!std::pair<_bstr_t
const ,_variant_t>::~pair<_bstr_t const ,_variant_t>+0x44
0012d418 12d749b2 AppContainer!std::pair<_bstr_t
const ,_variant_t>::`scalar deleting destructor'+0x25
0012d470 12d73d46 AppContainer!std::_Destroy+0x22
0012d4cc 12d72cb5 AppContainer!std::_Tree<_bstr_t,std::pair<_bstr_t
::_Kfn,std::less<_bstr_t>,std::allocator<_variant_t> >::_Destval+0x26
0012d550 12d78e2d AppContainer!std::_Tree<_bstr_t,std::pair<_bstr_t
::_Kfn,std::less<_bstr_t>,std::allocator<_variant_t> >::erase+0x825
0012d5b0 12d78af5 AppContainer!
std::map said:
::erase+0x2d
0012d654 12d788f1 AppContainer!CPropertyContainer::RemoveMapObject
+0x1c5
0012d6b8 12d796b0 AppContainer!CPropertyContainer::~CPropertyContainer
+0x41
0012d71c 12d77335 AppContainer!
ATL::CComObject<CPropertyContainer>::~CComObject<CPropertyContainer>
+0x70
0012d774 12d79758 AppContainer!
ATL::CComObject<CPropertyContainer>::`scalar deleting destructor'+0x25
0012d7dc 79e8dbde AppContainer!
ATL::CComObject<CPropertyContainer>::Release+0x48
0012d830 79e8db4a mscorwks!ReleaseTransitionHelper+0x5f
0012d878 79e8dac5 mscorwks!SafeReleaseHelper+0x89
0012d8ac 79f27983 mscorwks!SafeRelease+0x2f
0012d8c4 79f2792e mscorwks!RCW::ReleaseAllInterfaces+0x49
0012d8f4 79f279dc mscorwks!RCW::ReleaseAllInterfacesCallBack+0xbd
0012d924 79f279b0 mscorwks!RCW::Cleanup+0x22
0012d92c 79f27997 mscorwks!RCWCleanupList::ReleaseRCWListRaw+0x14
0012d95c 79f277e5 mscorwks!RCWCleanupList::ReleaseRCWListInCorrectCtx
+0x97
0012d96c 77525fbe mscorwks!CtxEntry::EnterContextCallback+0x94
0012d988 77e7a19c ole32!CRemoteUnknown::DoCallback+0x7a
0012d9a4 77ef321a RPCRT4!Invoke+0x30
0012dda8 77ef3bf3 RPCRT4!NdrStubCall2+0x297
0012de00 77600c31 RPCRT4!CStdStubBuffer_Invoke+0xc6
0012de40 77600bdb ole32!SyncStubInvoke+0x33
0012de88 7750f237 ole32!StubInvoke+0xa7
0012df60 7750f15c ole32!CCtxComChnl::ContextInvoke+0xe3
0012df7c 7750fc79 ole32!MTAInvoke+0x1a
0012dfa8 77600e3b ole32!STAInvoke+0x4a
0012dfdc 776009bc ole32!AppInvoke+0x7e
0012e0b0 77600df2 ole32!ComInvokeWithLockAndIPID+0x2e0
0012e0dc 7750fcb3 ole32!ComInvoke+0x60
0012e0f0 7750fae9 ole32!ThreadDispatch+0x23
0012e108 77d48744 ole32!ThreadWndProc+0xfe
0012e134 77d48826 USER32!InternalCallWinProc+0x28
0012e19c 77d489dd USER32!UserCallWinProcCheckWow+0x150
0012e1fc 77d48a20 USER32!DispatchMessageWorker+0x306
0012e20c 77512c02 USER32!DispatchMessageW+0xf
0012e23c 77512761 ole32!CCliModalLoop::peekRPCAndDDEMessage+0x4c
0012e250 77557227 ole32!CCliModalLoop::BlockFn+0x5e
0012e2c4 79f27b88 ole32!CoWaitForMultipleHandles+0xcf
0012e2e4 79f27acf mscorwks!NT5WaitRoutine+0x51
0012e350 79f27a33 mscorwks!MsgWaitHelper+0xa5
0012e370 79f17493 mscorwks!Thread::DoAppropriateAptStateWait+0x28
0012e3f4 79f1732f mscorwks!Thread::DoAppropriateWaitWorker+0x144
0012e444 79f27cf0 mscorwks!Thread::DoAppropriateWait+0x40
0012e494 79f27c76 mscorwks!Thread::JoinEx+0x86
0012e4a0 79f27c52 mscorwks!Thread::Join+0x13
0012e4f0 79f20743 mscorwks!
RCWCleanupList::CleanupWrappersInCurrentCtxThread+0x15a
0012e4f8 79f20665 mscorwks!RCW::Initialize+0x77
0012e52c 79f1dc99 mscorwks!RCW::CreateRCW+0x51
0012e59c 79f1c9a5 mscorwks!COMInterfaceMarshaler::CreateObjectRef+0x4d
0012e5fc 79f1c110 mscorwks!COMInterfaceMarshaler::FindOrCreateObjectRef
+0xb4
0012eabc 79f82a1c mscorwks!GetObjectRefFromComIP+0x1b4
0012eadc 79f82a01 mscorwks!UnmarshalObjectFromInterface+0x19
0012eaf8 79f1e19d mscorwks!
InterfaceMarshalerBase::ConvertSpaceNativeToCLR+0x30
0012eb00 79f1e0b2 mscorwks!
DefaultMarshalOverrides<InterfaceMarshalerBase>::MarshalNativeToCLROut
+0x11
0012ed3c 79f1f206 mscorwks!RunML+0x4f9
0012ee58 79f1ed6a mscorwks!COMToCLRWorkerBody+0x10f
0012eeb4 79f1ec81 mscorwks!COMToCLRWorkerDebuggerWrapper+0x37
0012f088 0173a271 mscorwks!COMToCLRWorker+0x164
WARNING: Frame IP not in any known module. Following frames may be
wrong.
0012f0b0 1425fac3 0x173a271
0012f1e0 142672fd AppController!CAppController::Display+0x184
0012f2d0 142504d2 AppController!CAppController::Create+0x683
0012f398 14236181 AppController!CAppController::CreateComponents+0x2da
0012f534 4599c7be AppController!CAppController::Open+0x607
0012f704 0108654d StateMgr!StateMgr::IState_Ope+0xded
0012f8c8 79f21268 TestMenu!Multiple::INotify_Notify+0xcc7
0012f9a8 045a0dd6 mscorwks!CLRToCOMWorker+0x196
0012f9e4 0ff37e88 0x45a0dd6
0012fa40 0ce5a340 0xff37e88
0012fa74 0ce59f28 0xce5a340
0012fac0 010ed2e2 0xce59f28
*** WARNING: Unable to verify checksum for C:\WINDOWS\assembly
\NativeImages_v2.0.50727_32\System.Windows.Forms
\5892bc4805482546977cc303fe56856e\System.Windows.Forms.ni.dll
0012fc28 7b0d02da 0x10ed2e2
0012fc48 7b0d02da System_Windows_Forms_ni+0x1002da
0012fc8c 7b072c44 System_Windows_Forms_ni+0x1002da
0012fcf8 7b07a73d System_Windows_Forms_ni+0xa2c44
0012fd74 77d48744 System_Windows_Forms_ni+0xaa73d
0012fda0 77d48826 USER32!InternalCallWinProc+0x28
0012fe08 77d489dd USER32!UserCallWinProcCheckWow+0x150
0012fe68 77d496d7 USER32!DispatchMessageWorker+0x306
0012fe78 6600a4a3 USER32!DispatchMessageA+0xf
0012feb8 6600a41a MSVBVM60!ThunderMsgLoop+0xfd
0012fecc 6600a3bc MSVBVM60!CMsoCMHandler::FPushMessageLoop+0x19
0012fefc 6600a2f8 MSVBVM60!SCM::FPushMessageLoop+0xb9
0012ff18 6600a2c3 MSVBVM60!SCM_MsoCompMgr::FPushMessageLoop+0x2b
0012ff3c 6600361c MSVBVM60!CMsoComponent::pushMsgLoop+0x26
0012ffb8 00404dba MSVBVM60!ThunRTMain+0x9b
0012fff0 00000000 AppMain!__vbaS+0xa
 
G

Guest

As far as I'm aware, it is not the CLR's job to release your unmanaged
memory. It has released the reference to your COMComp2 which is trying to
release COMComp1 from a variant. You need to handle this nicely in your C++
and VB code. The CLR doesnt have control over the memory for these operations.
I think its your bug, not the CLR's
 
Top