RCW终结器访问冲突

 R-hehe 发布于 2023-02-12 22:58

我正在使用COM interop在使用VS2012/.NET 4.5/Win8.1的非托管应用程序中创建托管插件.所有的互操作似乎都没问题,但是当我关闭应用程序时,我得到了一个MDA异常,告诉我在发布完成期间RCW持有的COM对象时发生了AV.

这是调用堆栈:

clr.dll!MdaReportAvOnComRelease::ReportHandledException()  + 0x91 bytes 
clr.dll!**SafeRelease_OnException**()  + 0x55 bytes 
clr.dll!SafeReleasePreemp()  + 0x312d5f bytes   
clr.dll!RCW::ReleaseAllInterfaces()  + 0xf3 bytes   
clr.dll!RCW::ReleaseAllInterfacesCallBack()  + 0x4f bytes   
clr.dll!RCW::Cleanup()  + 0x24 bytes    
clr.dll!RCWCleanupList::ReleaseRCWListRaw()  + 0x16 bytes   
clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx()  + 0x9c bytes  
clr.dll!RCWCleanupList::CleanupAllWrappers()  + 0x2cd1b6 bytes  
clr.dll!RCWCache::ReleaseWrappersWorker()  + 0x277 bytes    
clr.dll!AppDomain::ReleaseRCWs()  + 0x120cb2 bytes  
clr.dll!ReleaseRCWsInCaches()  + 0x3f bytes 
clr.dll!InnerCoEEShutDownCOM()  + 0x46 bytes    
clr.dll!WKS::GCHeap::**FinalizerThreadStart**()  + 0x229 bytes  
clr.dll!Thread::intermediateThreadProc()  + 0x76 bytes  
kernel32.dll!BaseThreadInitThunk()  + 0xd bytes 
ntdll.dll!RtlUserThreadStart()  + 0x1d bytes    

我的猜测是应用程序已经销毁了它的COM对象,其中一些引用被传递给托管插件 - 而对RCW的IUnknown :: Release的调用让它变得繁荣.

我可以在输出窗口(VS)中清楚地看到应用程序已经开始卸载其中的一些dll.

'TestHost.exe': Unloaded 'C:\Windows\System32\msls31.dll'
'TestHost.exe': Unloaded 'C:\Windows\System32\usp10.dll'
'TestHost.exe': Unloaded 'C:\Windows\System32\riched20.dll'
'TestHost.exe': Unloaded 'C:\Windows\System32\version.dll'
First-chance exception at 0x00000001400cea84 in VST3PluginTestHost.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
First-chance exception at 0x00000001400cea84 in VST3PluginTestHost.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
Managed Debugging Assistant 'ReportAvOnComRelease' has detected a problem in 'C:\Program Files\Steinberg\VST3PluginTestHost\VST3PluginTestHost.exe'.
Additional Information: An exception was caught but handled while releasing a COM interface pointer through Marshal.Release or Marshal.ReleaseComObject or implicitly after the corresponding RuntimeCallableWrapper was garbage collected. This is the result of a user refcount error or other problem with a COM object's Release. Make sure refcounts are managed properly.  The COM interface pointer's original vtable pointer was 0x406975a8. While these types of exceptions are caught by the CLR, they can still lead to corruption and data loss so if possible the issue causing the exception should be addressed

所以我虽然会管理自己的生命,并写了一个调用Marshal.ReleaseComObject的ComReference类.这不能正常工作,在阅读之后,我不得不同意在一个自由传递参考文献的场景中调用Marshal.ReleaseComObject,这不是一个好主意. Marshal.ReleaseComObject被认为是危险的

所以问题是:有没有办法管理这种情况,以便在退出主机应用程序时不会导致AV?

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有