【问题标题】:Visual Studio debugger stops hitting breakpoints in mixed debugging modeVisual Studio 调试器在混合调试模式下停止命中断点
【发布时间】: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。 实验表明:

  1. 没有附加调试器时一切正常。
  2. 在使用纯本机调试时(通过Service console app 或附加到已在纯本机模式下运行的进程后),一切正常(包括调试)。
  3. 在混合(即本机 + 托管)调试模式下,无论 GUI application 是通过调试启动还是调试器附加到工作进程,问题都会重现。
  4. 在调试和发布模式下都存在问题,但作用不同。在调试版本中会出现疯狂的调试问题(“调试损坏”),但在发布时它只是在内部某处崩溃(“内部崩溃”)。

完整的运行列表可见here

主要问题

以前有人见过类似的行为吗?这种行为的原因可能是什么?有办法解决吗?

【问题讨论】:

    标签: c# c++ debugging visual-studio-2013 breakpoints


    【解决方案1】:

    禁用 MSVC 的新托管调试引擎有助于解决此问题。可以通过转到工具 > 选项 > 调试 > 常规 > 勾选“使用托管兼容模式”来完成。


    在尝试找到解决此问题的方法时,我已发布 the following question。 Hans Passant 不仅发布了解决方法,还发布了我的主要问题的解决方案。在 C++/CLI 互操作的情况下,新的调试引擎似乎无法正常工作。

    P.S.鉴于症状非常独特和疯狂,我决定发布完整的问题和答案,希望这些信息可以帮助一些未来有类似问题的人。

    【讨论】:

    • “使用托管兼容模式”刚刚为我解决了这个问题。
    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 2019-03-19
    • 2011-07-02
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多