我们在大型服务器应用程序中遇到COM运行时间歇性灾难性故障。
以下是我们所拥有的:
作为Windows服务运行的服务器进程托管了许多用C ++ / ATL编写的自由线程COM组件。用C ++ / MFC和.NET编写的多个客户端进程通过在同一台机器上交叉进行COM调用(包括.NET互操作)来使用这些组件。操作系统是Windows Server 2008终端服务器(32位)。 整个软件套件是内部开发的,我们有所有组件的源代码。跟踪工具包会写出操作期间生成的错误和异常。
发生了什么:
经过一段时间的平稳航行(5天到3周)后,服务器的COM运行时似乎因这些症状的任何组合而崩溃:
CoInitializeEx(COINIT_MULTITHREADED)调用因CO_E_INIT_TLS(0x80004006)而失败
所有进行中的COM活动继续运行,CCI适用于CLSCTX_INPROC_SERVER。
唯一的补救措施是重启破损的服务。
其他(相关)观察:
跟踪确实引入了一些部分同步,因此可以隐藏多线程竞争条件效果。另一方面,在具有超线程的更多核上运行并行运行更多线程并增加故障率。
是否有人遇到类似的行为,甚至实际上遇到过RPC_E_INVALID_HEADER HRESULT?几乎没有关于该特定错误及其潜在原因的有用信息。 有没有办法窥探COM运行时内部以获取有关COM的私有资源池使用的更多有用信息,如内存,句柄,同步原语?可以一个过程'是否监控TLS插槽状态(CO_E_INIT_TLS)?
答案 0 :(得分:3)
我们有信心将此缺陷的原因归结为.NET Framework 4.0中的资源泄漏。
我们在.NET 4.0上运行的服务器应用程序(clr.dll:4.0.30319.1)的安装显示了间歇性的COM运行时故障,可以通过将.NET框架更新到4.5.1版(clr.dll:4.0)来轻松修复。 30319.18444)
以下是我们如何找出原因:
在网络上进行的搜索在MSDN论坛中显示了一个条目:http://social.msdn.microsoft.com/Forums/pt-BR/f928f3cc-8a06-48be-9ed6-e3772bcc32e8/windows-7-x64-com-server-ole32dll-threads-are-not-cleaned-up-after-they-end-causing-com-client?forum=vcmfcatl
那里的OP描述了在使用互操作应用程序运行COM服务器一段时间(一个月左右)后,从CoCreateInstanceEx(CLSCTX_LOCAL_SERVER)接收HRESULT RPC_X_BAD_STUB_DATA(0x800706f7)。他将问题跟踪到线程资源泄漏,这可以通过ole32.dll内部的递增变量间接观察到:EventPoolEntry :: s_initState一旦其值变为0xbfff导致CCI失败...
在我们错误的安装中检查EventPoolEntry :: s_initState显示其值在大约开始时显示。重启后0x8000,然后在正常负载下运行应用程序,每小时不断增加100到200+。一旦s_initState命中0xbfff,应用程序就会因原始问题中描述的所有症状而失败。 MSDN论坛中的OP怀疑COM线程本地资源泄漏,因为他观察到对线程初始化和线程清理的非对称调用 - 5 x init与3 x cleanup。
通过在几天的过程中自动跟踪s_initState的值,我们能够证明从原始4.0将.NET框架更新到4.5.1完全消除了泄漏。