调试 COM 对象析构函数时出现奇怪的崩溃

发布于 2024-12-01 01:57:48 字数 621 浏览 3 评论 0原文

我的应用程序是 C# 和 C++ 代码的混合。用C#编写的启动模块在初始化阶段通过COM(组件对象模型)机制加载C++模块。一切正常,直到我决定向 C# 部分添加 wcf 服务。所有 wcf 服务调用都使用 COM 路由到 C++ 代码。添加一些新方法后,我注意到输出窗口中存在内存泄漏。因此,我向 C++ 类的析构函数添加了断点,如屏幕截图所示。从这时起,奇怪的事情开始发生。程序到达断点后意外崩溃。第一个奇怪的事情是,当我在没有设置断点的情况下运行程序时,它会优雅地结束。第二个奇怪的事情是程序崩溃的方式就像它在没有调试器的情况下运行一样。单击“在调试器中打开”按钮(或类似的内容)后,我收到错误消息:“程序已在调试器下打开。”输出窗口中没有任何消息可以指出错误的来源,也没有可疑的代码。 当将消息框添加到析构函数开始时,它会显示几分之一秒,然后整个应用程序关闭(不添加用户机会阅读消息框中显示的内容)。拼命寻找任何线索。

PS 仅当 wcf 方法至少被调用一次时才会出现问题。不取决于此特定调用中的程序流是否路由到 C++ 级别。

在此处输入图像描述

在此输入图像描述

My application is a mix of C# and C++ code. Startup module written in C# loads during initialization phase C++ module through COM (Component Object Model) mechanism. All was functioning correctly until I decided to add to C# part a wcf service. All wcf service calls are routed to C++ code using COM. After adding some new methods I noticed memory leaks in output window. So I added breakpoint to desctructor of C++ class as can be seen from screenshot. From this point on weird things started to happen. After program reaches breakpoint it unexpectedly crashes. First weird thing is that when I run program without breakpoint being set it ends graciously. Second weird thing is that the way program crashes is as if it were running without debugger. After clicking on button "Open in debugger" (or something like this) I get error message: "Program is already opened under debugger." None message in output window that could point me to the source of the error, none suspicious code.
When adding message box to destructor beginning it displays for fraction of second and then whole application closes (without adding user opportunity to read whats displayed in message box). Desperately searching for any clue.

P.S. Problems occurs only when wcf method was called at least once. Doesn't depend if program flow in this particular call was routed to C++ level or not.

enter image description here

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慕巷 2024-12-08 01:57:48

当从 C++ 调用 C# 时,有时垃圾收集器在程序结束之前不会正确调用。尝试在 C# 代码末尾强制进行垃圾回收。

When calling C# from C++ sometimes the garbage collector doesn't properly get called before program end. Try forcing garbage collection at the end of your C# code.

各自安好 2024-12-08 01:57:48

通过以下代码解决:

public void Dispose()
{
    Marshal.Release(internal_interface_ptr);
    internal_interface_ptr = IntPtr.Zero;
    Marshal.ReleaseComObject(internal_interface);
    Marshal.ReleaseComObject(internal_interface);
    internal_interface = null;
} 

除此之外,另一个引用还挂在 C++ 代码中。总而言之,我的主要错误是忘记在 C# 代码中显式释放 COM 对象。即使垃圾收集器承担管理内存的任务,对于用其他编程语言编写的模块来说也不是这样。最近,当要从内存中卸载特定的动态链接库时,会调用 COM 析构函数,这会导致问题。希望我解释得足够清楚。

Resolved by following code:

public void Dispose()
{
    Marshal.Release(internal_interface_ptr);
    internal_interface_ptr = IntPtr.Zero;
    Marshal.ReleaseComObject(internal_interface);
    Marshal.ReleaseComObject(internal_interface);
    internal_interface = null;
} 

Beside this one other reference was hanging in C++ code. So to make conclusion, main mistake on my part was forgetting to explicitly release COM object in C# code. Even if garbage collector takes task of managing memory this isn't true for modules written in other programming languages. COM destructor was called very lately when particular dynamic linked library was to be unloaded from memory and this caused problems. Hope I explained it sufficient clearly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文