【发布时间】:2016-01-23 08:27:36
【问题描述】:
我在 MSVC2013 中的混合调试存在严重问题。从本机 C++ DLL 调用 COM 方法后,调试器不再在断点处停止。
代码结构
上图展示了代码的整体结构。
我有一个包含大约 10 个 C# 项目、大约 50 个 C++ 本机项目和一个 C++/CLI 项目的解决方案,作为托管世界和本机世界之间的桥梁。启动项目是一个 C# WPF 项目 (GUI Application),它在内部调用 C++/cli 项目 (Bridge),进而调用各种原生 C++ Dlls (Various libraries)。或者,我可以将 C++ 控制台应用程序 (Service console app) 作为启动项目,仅用于测试目的。
我已经实现了一个库来从Autodesk Inventor 文档文件中导入一些信息。 Inventor Apprentice COM 服务器(图片上的Inventor Apprentice)用于实现它,它与Inventor View 2015 一起免费下载。作为第一步,导入是在一个独立的本机 C++ 控制台应用程序中实现的,并且一切正常。然后它被改编为作为原生 C++ dll (Import library) 在整个基础架构中使用,调试地狱开始了。
症状
“调试失败”。在调试构建中,在Import library 中调用以下 COM 方法后:
auto pComponentDefinitions = pDocument->GetComponentDefinitions();
C++ 代码中的断点不再被命中。即使我在另一个 DLL 的代码中设置了断点,它也不会被命中。断点仍然显示为完整的红色圆圈,因此这与 PDB 问题无关。
应用程序本身继续执行,一段时间后我可以在 GUI 中看到正确的数据导入结果,这意味着 Import library 已正确执行。之后,我可以使用 Break All 按钮暂停 GUI Application,在这种情况下,主线程显示为深深卡在 Inventor 的一个 dll (rse.dll) 中,这不可能是真的,因为该线程已完成导入并且甚至返回正确的结果。
在输出窗口中,我可以看到以下消息,出现在有问题的 COM 方法调用期间(访问冲突在 Apprentice 中似乎很正常):
First-chance exception at 0x000007FEDD451F0C (rse.dll) in GUIApplication.exe: 0xC0000005: Access violation writing location 0x000007FFFDE3AFCC.
The Common Language Runtime cannot stop at this exception. Common causes include: incorrect COM interop marshalling and memory corruption. To investigate further use native-only debugging.
First-chance exception at 0x000007FEDD455F6C (rse.dll) in GUIApplication.exe: 0xC0000005: Access violation writing location 0x000007FFFDE3EE6C.
我尝试在编译时将断点嵌入到代码中,方法是在有问题的导入代码前后插入__debugbreak()。第一个被命中(如果调试还没有被破坏),但第二个没有。另一方面,调试器清楚地注意到它,因为它将以下消息写入输出窗口:
The process hit a breakpoint the Common Language Runtime cannot continue from.
This may be caused by an embedded breakpoint in the native runtime or a breakpoint set in a can't-stop region.
To investigate further, use native-only debugging.
Google 根本没有为此诊断消息提供任何结果。听起来 MSVC 认为它在调试托管代码,实际上是本机代码。
“调用崩溃”。 在发布版本的情况下,在混合调试模式下运行应用程序会导致在有问题的 COM 调用期间 rse.dll 内部崩溃。
再现性
我使用 MSVC 2013 更新 4。项目以 x64 模式构建。使用网络框架 v4.0。使用 Inventor 2015 中的 Inventor Apprentice。 实验表明:
- 没有附加调试器时一切正常。
- 在使用纯本机调试时(通过
Service console app或附加到已在纯本机模式下运行的进程后),一切正常(包括调试)。 - 在混合(即本机 + 托管)调试模式下,无论
GUI application是通过调试启动还是调试器附加到工作进程,问题都会重现。 - 在调试和发布模式下都存在问题,但作用不同。在调试版本中会出现疯狂的调试问题(“调试损坏”),但在发布时它只是在内部某处崩溃(“内部崩溃”)。
完整的运行列表可见here。
主要问题
以前有人见过类似的行为吗?这种行为的原因可能是什么?有办法解决吗?
【问题讨论】:
标签: c# c++ debugging visual-studio-2013 breakpoints