使用 C# 插件挂在 COM 应用程序中
我遇到了一个问题,我们的应用程序挂在客户的机器上,我已经使用了几天而没有解决。从我们所看到的情况来看,这个问题是相当随机出现的,尽管事实可能并非如此。客户还报告说,当应用程序挂起时,CPU 就会达到峰值。
问题是我不知道应用程序在哪里失败(挂起)。我们还有几个用 C# 编写的插件,作为主 COM 应用程序的插件。
我已设法让客户在出现问题的计算机上使用 ProcExp 进行 MiniDump。不过,我对 WinDBG 或 MiniDumps 也不是很熟悉。我运行了 !analyze -v
和 !analyze -v -hang
,这会产生一些输出,包括下面的堆栈。据我所知,应用程序似乎正在转换为我们的 C# 插件 (CLR) 之一,然后再次返回到 COM,这应该是返回到可供插件使用的主应用程序的接口。但然后呢?是否可以从这个堆栈中多说一些东西?
如果重要的话,主应用程序是用 VB6 编写的。
0012da70 7e3693e9 7e3693a8 0012daf0 00000000 ntdll!KiFastSystemCallRet
0012da9c 7e37a43b 0012daf0 00000000 0000000f user32!NtUserPeekMessage+0xc
0012dac8 7348e6fd 0012daf0 00000000 0000000f user32!PeekMessageA+0xeb
0012db1c 77532a9c 00d03774 00000000 00000000 msvbvm60!CMsgFilter::MessagePending+0x21f
0012db60 77532a48 00000102 0012dbec 00000001 ole32!CCliModalLoop::HandlePendingMessage+0x40
0012dba8 7751eda6 80010116 80010115 00000000 ole32!CCliModalLoop::HandleWakeForMsg+0x46
0012dbbc 77547297 0012ddf0 00000001 0012dbe8 ole32!CCliModalLoop::BlockFn+0x8b
0012dc30 0ae8a2fd 00000002 00000001 00000001 ole32!CoWaitForMultipleHandles+0xcf
0012dc50 0ae8a264 00000000 00000001 00000001 mscorwks!NT5WaitRoutine+0x51
0012dcbc 0ae8a1c8 00000001 0012ddf0 00000000 mscorwks!MsgWaitHelper+0xa5
0012dcdc 0af3ccd0 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateAptStateWait+0x28
0012dd60 0af3cd65 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWaitWorker+0x13c
0012ddb0 0ae8c026 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWait+0x40
0012de00 0ae90f4c 00000001 05ae5c80 0012de60 mscorwks!Thread::JoinEx+0x86
0012de10 0b00ea40 00000001 00000001 5bdf0a2d mscorwks!Thread::Join+0x14
0012de60 0af0b9a7 00000001 0012deb0 0af0ba10 mscorwks!RCWCleanupList::CleanupWrappersInCurrentCtxThread+0x15a
0012de6c 0af0ba10 001df674 0012df10 5bdf0afd mscorwks!RCW::Initialize+0x78
0012deb0 0af0b6a7 001df674 0012df10 5bdf0b6d mscorwks!RCW::CreateRCW+0x84
0012df20 0af0b7b5 00000000 0012df5c 5bdf0b21 mscorwks!COMInterfaceMarshaler::CreateObjectRef+0x45
0012df6c 0ae892a8 5bdf3065 0012e6c8 0012e6c8 mscorwks!COMInterfaceMarshaler::FindOrCreateObjectRef+0xac
0012e428 0ae89444 001df658 11a11014 00000001 mscorwks!GetObjectRefFromComIP+0x1ec
0012e448 0ae894ab 05b3b0a8 001df658 0e896204 mscorwks!UnmarshalObjectFromInterface+0x19
0012e464 0af164d1 0012e6c8 0012e6ac 0af164c1 mscorwks!InterfaceMarshalerBase::ConvertSpaceNativeToCLR+0x30
0012e470 0af164c1 0012e748 0012e738 5bdf32e1 mscorwks!DefaultMarshalOverrides<InterfaceMarshalerBase>::ReturnCLRFromNativeRetval+0xb
0012e6ac 0aeb4bff 11741a76 0012e734 0012e74c mscorwks!RunML+0x9ac
0012e780 11740172 05ae5c80 0012e7d4 501b6046 mscorwks!CLRToCOMWorker+0x25f
...
... Stack begins down here in our main COM application.
编辑1: 我在阅读其他论坛帖子后得到的一些想法。在我看来,挂起是在将数据类型从 .NET 编组到 COM 之后引入的。现在我读到了另一个问题< /a> 这似乎源于这样一个事实:传递给 COM 方法的局部变量被垃圾收集,因此 VB6 运行时在处理释放内存。另一篇文章并不完全是这个问题,但它让我思考。
在调用 COM 的 .NET 代码中,我们有这种类型的代码
void SomeNETMethod(MyObject obj, bool doIt) {
string someString = obj.SomeString;
this.myComComponent.DoItInCOM(ref someString, ref doIt); // This is where it hangs.
}
ref bool
以及直接从方法到方法传递的参数是否有任何关系?正如你所看到的,我在这里的黑暗中跌跌撞撞......
I've got a problem where our application hangs on our customers' machines that I've been on for days now without solving. The problem arises quite randomly from what we've seen, even though that may not be the true case. The customer also reports that the CPU is peaking when the application hangs.
The problem is that I've no idea where the application is failing (hanging). We have a couple of plugins written in C# as plugins for the main COM application as well.
I've managed to get the customer to take a MiniDump with ProcExp on a machine where the problem occurred. However, I'm not very familiar with WinDBG or MiniDumps either for that matter. I've run !analyze -v
and !analyze -v -hang
, which produces some output, including the stack below. For what I'm able to tell, it seems the application is transitioning into one of our C# plugins (CLR) and then back again to COM, which ought to be an interface back to the main application that is available to the plugins. But then what? Is it possible to say something more from this stack?
The main application is written in VB6 if that matters.
0012da70 7e3693e9 7e3693a8 0012daf0 00000000 ntdll!KiFastSystemCallRet
0012da9c 7e37a43b 0012daf0 00000000 0000000f user32!NtUserPeekMessage+0xc
0012dac8 7348e6fd 0012daf0 00000000 0000000f user32!PeekMessageA+0xeb
0012db1c 77532a9c 00d03774 00000000 00000000 msvbvm60!CMsgFilter::MessagePending+0x21f
0012db60 77532a48 00000102 0012dbec 00000001 ole32!CCliModalLoop::HandlePendingMessage+0x40
0012dba8 7751eda6 80010116 80010115 00000000 ole32!CCliModalLoop::HandleWakeForMsg+0x46
0012dbbc 77547297 0012ddf0 00000001 0012dbe8 ole32!CCliModalLoop::BlockFn+0x8b
0012dc30 0ae8a2fd 00000002 00000001 00000001 ole32!CoWaitForMultipleHandles+0xcf
0012dc50 0ae8a264 00000000 00000001 00000001 mscorwks!NT5WaitRoutine+0x51
0012dcbc 0ae8a1c8 00000001 0012ddf0 00000000 mscorwks!MsgWaitHelper+0xa5
0012dcdc 0af3ccd0 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateAptStateWait+0x28
0012dd60 0af3cd65 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWaitWorker+0x13c
0012ddb0 0ae8c026 00000001 0012ddf0 00000000 mscorwks!Thread::DoAppropriateWait+0x40
0012de00 0ae90f4c 00000001 05ae5c80 0012de60 mscorwks!Thread::JoinEx+0x86
0012de10 0b00ea40 00000001 00000001 5bdf0a2d mscorwks!Thread::Join+0x14
0012de60 0af0b9a7 00000001 0012deb0 0af0ba10 mscorwks!RCWCleanupList::CleanupWrappersInCurrentCtxThread+0x15a
0012de6c 0af0ba10 001df674 0012df10 5bdf0afd mscorwks!RCW::Initialize+0x78
0012deb0 0af0b6a7 001df674 0012df10 5bdf0b6d mscorwks!RCW::CreateRCW+0x84
0012df20 0af0b7b5 00000000 0012df5c 5bdf0b21 mscorwks!COMInterfaceMarshaler::CreateObjectRef+0x45
0012df6c 0ae892a8 5bdf3065 0012e6c8 0012e6c8 mscorwks!COMInterfaceMarshaler::FindOrCreateObjectRef+0xac
0012e428 0ae89444 001df658 11a11014 00000001 mscorwks!GetObjectRefFromComIP+0x1ec
0012e448 0ae894ab 05b3b0a8 001df658 0e896204 mscorwks!UnmarshalObjectFromInterface+0x19
0012e464 0af164d1 0012e6c8 0012e6ac 0af164c1 mscorwks!InterfaceMarshalerBase::ConvertSpaceNativeToCLR+0x30
0012e470 0af164c1 0012e748 0012e738 5bdf32e1 mscorwks!DefaultMarshalOverrides<InterfaceMarshalerBase>::ReturnCLRFromNativeRetval+0xb
0012e6ac 0aeb4bff 11741a76 0012e734 0012e74c mscorwks!RunML+0x9ac
0012e780 11740172 05ae5c80 0012e7d4 501b6046 mscorwks!CLRToCOMWorker+0x25f
...
... Stack begins down here in our main COM application.
Edit 1:
Some thoughts that I've got after reading some other forum posts. It seems to me that the hanging is introduced following a marshaling of data types from .NET to COM. Now I've read about another problem which seemed to originate in the fact that local variables passed into a COM method were garbage collected and thus the VB6 run time had problems dealing with the deallocated memory. That other post was not exactly this problem, but it made me think.
In the .NET code calling into COM we have this type of code
void SomeNETMethod(MyObject obj, bool doIt) {
string someString = obj.SomeString;
this.myComComponent.DoItInCOM(ref someString, ref doIt); // This is where it hangs.
}
Could the ref bool
as well as the directly from method to method passed parameter have anything to do with anything? As you can see, I'm stumbling in the dark here...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
检查“DoItInCOM”方法,因为内核转储指示正在显示模式对话框(可能是由于 COM 方法调用中的错误所致)。.
NET 参数已正确编组到 COM 端。如果您使用某些非标准 C# 类型,您可能会遇到序列化问题,但这里的情况并非如此。
如果您在 VB 代码中放置“On Error Goto”处理程序,则可能会抑制在 UI 线程上生成消息的错误。如果错误级别较低(VB 运行时抛出该错误),您将需要直接修复 COM 组件来解决该问题。另请查看 Windows 事件查看器中的 VB 运行时起源消息以获取更多信息。
Review your "DoItInCOM" method as the kernel dump indicates a modal dialog is being displayed (likely as a result of an error within the COM method call.)
The .NET parameters are correctly being marshalled over to the COM side. If you were using some non-standard C# type you may run into a problem with serialization but this is not the case here.
If you place an "On Error Goto" handler in the VB code you can likely suppress errors that would generate a message on the UI thread. If the error is lower level (the VB runtime is throwing it) you will need to resolve that problem with fixes to the COM component directly. Also review the Windows Event Viewer for VB Runtime origintatin messages for further information.