如何附加调试器以从托管(C#)包装器进入本机(C++)代码?

Posted

技术标签:

【中文标题】如何附加调试器以从托管(C#)包装器进入本机(C++)代码?【英文标题】:How to attach debugger to step into native (C++) code from a managed (C#) wrapper? 【发布时间】:2010-09-08 15:23:12 【问题描述】:

我有一个从 C# 代码调用的 C++ 函数调用的包装器。如何在 Visual Studio 中附加调试器以单步执行本机 C++ 代码?

这是我在 C++ 文件中定义的调用 GetData() 的包装器:

    [DllImport("Unmanaged.dll", CallingConvention=CallingConvention.Cdecl, 
               EntryPoint = "GetData", BestFitMapping = false)]
        public static extern String GetData(String url);

代码崩溃,我想调查根本原因。

谢谢, 尼基尔

【问题讨论】:

【参考方案1】:

检查项目属性页面上的调试选项卡。应该有一个“启用非托管代码调试”复选框。当我们为旧的 c++ DLL 开发新的 .NET UI 时,这对我有用。

如果您的非托管 DLL 是从另一个项目构建的(有一段时间我们的项目是使用 VS6 构建的),请确保您有 DLL 的 pdb 文件以方便调试。

另一种方法是使用 C# exe 作为目标 exe 从 DLL 项目中运行,然后您可以正常调试您的 DLL。

【讨论】:

【参考方案2】:

除了 Lou 对启动调试器的建议之外,您还可以通过单击“附加到进程”对话框中的“选择...”并同时选择“托管代码”来选择附加到现有进程时使用的调试引擎' 和 '本机代码'。

以这种方式调试称为混合模式调试。请参阅此blog post 了解一些提示。

我相信 64 位进程不支持此功能......尽管在这一点上很可能是错误的。

【讨论】:

感谢您的跟进。我不倾向于使用“附加到处理”,所以我忘记了这是另一种选择。干杯。【参考方案3】:

致任何使用 WinDbg 的人:

1>设置符号

看看这些命令。 (帮助:在控制台.hh

.sympath
.sympath+ 
.symfix

2>设置源路径

.srcpath

3>加载 SOS 扩展以调试托管/混合模式程序。

(确保您正确设置了扩展路径)

添加 Microsoft.NET\Framework\v2.0.50727 for x86 using-

.extpath 

为要加载的 clr 设置断点。

sxe ld:mscorwks

(F5/克) (等待 mscorwks.dll 上的 ModLoad BP)

确保您没有已加载重复的 sos 扩展。见:

.chain

现在我们已准备好加载 sos 扩展。 :)

.loadby sos mscorwks

4> 重新加载所有符号..

.reload

现在一切就绪:)

(YMMV)

【讨论】:

【参考方案4】:

64 位模式不支持混合调试(自 Visual Studio 2008 起)。

【讨论】:

你能发表任何关于这个主题的文章吗?

以上是关于如何附加调试器以从托管(C#)包装器进入本机(C++)代码?的主要内容,如果未能解决你的问题,请参考以下文章

在C ++ / CLI中通过包装器(派生的托管类)调用派生本机类的重写方法

Visual Studio 如何加载库?

C# 使用 CLI 包装器调用非托管 C++

用于 C++ 的 C# 包装器,但仅编译为静态库

调试包含在 C++/CLI DLL 中的静态库时,调试器不会进入本机代码

使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++