问题描述
我在MSVC2013中混合调试有一个严重的问题。从原生C ++ DLL调用COM方法后,调试器不会再在断点处停止。
代码结构
上图显示了代码的整体结构。
我有一个单独的解决方案,大约有十个C#项目,大约五十个C ++本地项目,一个C ++ / CLI项目作为管理和本机世界之间的桥梁。启动项目是一个C#WPF项目(
GUI应用程序
),它内部调用C ++ / cli项目( Bridge
),反过来调用各种本机C ++ Dll(各种库
)。或者,我可以将C ++控制台应用程序(服务控制台应用程序
)作为启动项目,仅用于测试目的。 我已经实施了一个库来从文档文件导入一些信息。 Inventor Apprentice COM服务器( Inventor Apprentice
在图片上)用于实现它,这是与。作为第一步,导入是在独立的本地C ++控制台应用程序中实现的,一切都正常。然后,它适合在整个基础架构中用作本地C ++ DLL(导入库
),并且调试开始。
症状
调试断开。在调试版本中,在导入库:
auto pComponentDefinitions = pDocument-> GetComponentDefinitions ();
C ++代码中的断点不再受到打击。即使我在另一个DLL的代码中设置了断点,也没有被打。断点仍然可视化为完整的红色圆圈,因此这与PDB问题无关。
应用程序本身继续执行,稍后我可以看到在GUI中可见的数据导入的正确结果,意味着导入库
已正确执行。之后,我可以暂停使用全部休息按钮的 GUI应用程序
,在这种情况下,主线程显示卡在其中一个Inventor的dll(rse.dll)中,不能为true,因为该线程已经完成导入,甚至返回正确的结果。
在输出窗口中,我可以看到以下消息,出现在有问题的COM方法调用(Apprentice中的访问冲突似乎是正常的):
0x000007FEDD451F0C(rse) .dll)在GUIApplication.exe:0xC0000005:访问冲突写入位置0x000007FFFDE3AFCC。
公共语言运行时不能停止在此异常。常见原因包括:错误的COM互操作编组和内存损坏。要进一步调查本机调试。
GUIApplication.exe中0x000007FEDD455F6C(rse.dll)的第一次异常:0xC0000005:访问冲突写入位置0x000007FFFDE3EE6C。
我已经尝试在编译时嵌入断点,通过插入。第一个被击中(如果调试尚未破坏),但第二个不是。另一方面,调试器清楚地注意到,因为它将以下消息写入Output窗口:
该进程触发了Common Language Runtime无法继续的断点。
这可能是由本地运行时中的嵌入式断点或不能停止区域中设置的断点引起的。
要进一步调查,请使用纯本机调试。
Google对此诊断消息没有任何结果。这听起来像MSVC认为是调试托管代码,这实际上是原生的。
崩溃的通话。如果发布版本,在混合调试模式下运行应用程序会在有问题的COM调用期间导致rse.dll中的崩溃。
重现性
我使用MSVC 2013 update 4.项目内置于x64模式。使用Net Framework v4.0。使用Inventor 2015的Inventor学徒。
实验表明:
- 没有调试器附加时,一切都OK。
- 一切工作正常(包括调试),当使用原生调试(通过
服务控制台应用程序
或附加到本机运行的进程后)。 >
- 在混合(即本机+管理)调试模式下,问题是复制,无论
GUI应用程序
是否启动,调试器或调试器被附加到工作过程。 - 调试和发布模式都有问题,但它的行为不同。在调试中,出现调试问题(调试已损坏),但在发布时,它只会在内部的某个地方崩溃(内部崩溃)。
完成的运行列表可以在看到。 / p>
主要问题
有没有人看过类似的行为?可能是这种行为的原因?有没有办法解决它?
禁用MSVC的新的托管调试引擎有助于解决问题。可以通过转到工具>选项>调试>常规>勾选使用管理的兼容性模式。
试图找到解决方案的问题,我已经发布了。汉斯·帕斯特(Hans Passant)不仅发布了一个解决方案,也解决了我的主要问题。似乎新的调试引擎在C ++ / CLI互操作的情况下没有正确的工作。
PS 鉴于症状是非常独特和疯狂的,我决定用完整的问题发表答案,希望这个信息可能会帮助未来有类似问题的人。
I have a severe problem with mixed debugging in MSVC2013. After a call to a COM method from a native C++ DLL, debugger does not stop at breakpoints any more.
Code structure
The picture above presents the overall structure of the code.
I have a single solution with about ten C# projects, about fifty C++ native projects, and one C++/CLI project serving as a bridge between managed and native worlds. Startup project is a C# WPF project (GUI Application
), it calls C++/cli project (Bridge
) internally, which in turn calls various native C++ Dlls (Various libraries
). Alternatively, I can make a C++ console application (Service console app
) as startup project for testing purposes only.
I have implemented a library to import some information from Autodesk Inventor document files. Inventor Apprentice COM server (Inventor Apprentice
on picture) is used to achieve it, which was freely downloaded alongside with Inventor View 2015. As a first step, the import was implemented in a standalone native C++ console application, and everything worked fine. Then it was adapted to be used in the whole infrastructure as a native C++ dll (Import library
), and the debugging hell started.
Symptoms
"debugging broken". In a debug build, after calling the following COM method in Import library
:
auto pComponentDefinitions = pDocument->GetComponentDefinitions();
breakpoints in C++ code are no longer hit. Even if I set a breakpoint in the code of another DLL, it is not hit. Breakpoints still visualize as full red circles, so this is not related to PDB issues.The application itself continues to execute, and some time later I can see the correct results of data import visible in GUI, meaning that Import library
has executed correctly. After that, I can pause the GUI Application
with Break All button, in which case the main thread is shown stuck deeply inside one of the Inventor's dlls (rse.dll), which cannot be true because that thread has finished import and has even returned correct results.
In the Output window, I can see the following messages, appearing during the problematic COM method call (access violations seem to be normal in 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.
I have tried to embed breakpoints into the code at the moment of compilation, by inserting __debugbreak() before and after the problematic import code. The first one is hit (if debugging is not yet broken), but the second one is not. On the other hand, debugger clearly notices it, because it writes the following message to Output window:
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 gives no results at all for this diagnostic message. It sounds like MSVC thinks it is debugging managed code, which is actually native.
"crashes in call". In case of release build, running the application in mixed debugging mode results in a crash inside rse.dll during the problematic COM call.
Reproducibility
I use MSVC 2013 update 4. Project is built in x64 mode. Net Framework v4.0 is used. Inventor Apprentice from Inventor 2015 is used.Experimentation shows that:
- Everything is OK when no debugger is attached.
- Everything works correctly (including debugging), when native-only debugging is used (either via
Service console app
or after attaching to already running process in native only mode). - In mixed (i.e. native + managed) debugging mode the problem reproduces regardless of whether
GUI application
was started with debugging or debugger was attached to a working process. - There is a problem both in debug and release modes, but it acts differently. In debug build crazy debugging issues arise ("debugging broken"), but in release it simply crashes somewhere inside ("crashes inside").
Full list of runs performed can be seen here.
The main question
Has anyone seen similar behavior before? What may be the cause of such behavior? Is there a way to fix it?
Disabling the new managed debugging engine of MSVC has helped to fix the issue. It can be done by going to Tools > Options > Debugging > General > tick "Use Managed Compatibility Mode".
While trying to find a workaround for the issue, I have posted the following question. Hans Passant has posted not only a workaround, but also a solution to my main problem. It seems that new debugging engine is not properly working in case of C++/CLI interop.
P.S. Given that the symptoms are quite unique and crazy, I decided to post the full question with the answer, hoping that this information may help some people with similar problems in future.
这篇关于Visual Studio调试器在混合调试模式下停止点击断点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!