Visual Studio调试器在混合调试模式下无法触发断点

9

我在MSVC2013中使用混合调试遇到了一个严重的问题。在从本地C++ DLL调用COM方法后,调试器不再在断点处停止。

代码结构

Scheme

上图展示了代码的整体结构。

我有一个单一的解决方案,大约有十个C#项目,约50个本地C++项目和一个用于管理和本地世界之间桥梁的C++/CLI项目。启动项目是一个C# WPF项目(GUI应用程序),它内部调用C++ / cli项目(Bridge),后者又调用各种本地C++ Dlls(Various libraries)。或者,我可以创建一个C++控制台应用程序(服务控制台应用程序)作为仅用于测试目的的启动项目。

我实现了一个库来导入一些来自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应用程序,此时主线程被卡在Inventor的一个dll(rse.dll)中,但这显然不可能是真的,因为该线程已经完成了导入并返回了正确的结果。

在输出窗口中,我可以看到以下消息,出现在存在问题的COM方法调用期间(在学徒中,访问冲突似乎是正常的):

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模式构建。使用Net Framework v4.0。使用来自Inventor 2015的Inventor Apprentice。 实验证明:

  1. 没有调试器附加时一切正常。
  2. 仅使用本机调试(通过Service console app或在本机模式下附加到已运行的进程后),一切都正常(包括调试)。
  3. 在混合(即本机+托管)调试模式下,无论是通过调试启动“GUI应用程序”还是附加调试器到工作进程,都会复制该问题。
  4. 在调试和发布模式下都存在问题,但表现不同。在调试版本中出现了疯狂的调试问题("调试中断"),但在发布版本中只是在某个地方崩溃("崩溃里面")。

可以在此处查看运行的完整列表。

主要问题

有人看到过类似的行为吗?这种行为的原因可能是什么?是否有方法来解决它?

1个回答

8
禁用MSVC的新托管调试引擎有助于解决问题。可以通过转到“工具”>“选项”>“调试”>“常规”>勾选“使用托管兼容性模式”来完成。
在试图解决这个问题时,我发布了以下问题。Hans Passant不仅提供了解决方法,还提供了解决我的主要问题的方案。似乎新的调试引擎在C++/CLI交互操作方面工作不正常。
附注:鉴于症状非常特殊和令人困惑,我决定以完整的问题和答案发布,希望这些信息可以帮助未来遇到类似问题的人们。

2
“使用托管兼容模式”对我来说解决了这个问题。 - Aaron Hudon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接