我有一个使用外部C++DLL的C#应用程序,由于某种原因,我不能再在Visual Studio中单步执行它的函数.我曾经可以,但现在,每次我try ,我都会在NTDLL内结束反汇编,而不是在我的C++函数中.如果我在C++代码中调用DebugBreak(),我会收到一条奇怪的错误消息,比如"命中了CLR无法处理的断点".

我在C#应用程序的调试配置文件中打开了"Enable native code debugging",关闭了"Hot Reload"和"Edit and Continue",这有时会给本机代码调试带来麻烦,但我仍然不能单步执行C++代码.

下面是我在C#端的函数声明:

[DllImport("Foo.dll"), SuppressGCTransition]
public static extern unsafe void DoSomething();

这是在C++端:

__declspec(dllexport) void DoSomething()
{
    ...
}

为什么我不能进入此功能?我使用的是Visual Studio 2022,17.5.3.

推荐答案

混合模式调试在这种情况下可能不起作用的最可能原因是:您在C#中对导入的C/C++函数应用的[DllImport]属性声明了SuppressGCTransition.这可能会使调用速度变得相当快,特别是在短调用的情况下,但它也会真正吓坏调试器.所以,如果你在C#中有类似这样的东西:

[DllImport("Foo.dll"), SuppressGCTransition]
public static extern unsafe void DoSomething();

您需要将其更改为下面的形式,否则DoSomething()内的任何断点都不会被命中,甚至对DebugBreak()的调用也不会被命中.

[DllImport("Foo.dll")]
public static extern unsafe void DoSomething();

微软明确声明了SuppressGCTransition breaks mixed-mode debugging,但当您试图追踪断点不起作用的原因时,很容易忘记这一事实:多年来,混合模式调试中出现了足够多的奇怪故障,当错误实际上是您自己的时,很容易将其归咎于Visual Studio.

(I wasted a lot more time today than I ought to have wasted on this exact issue, so hopefully this answer will help someone avoid wasting that time in the future!)

Csharp相关问答推荐

如何从Date中剥离Timezone部分以仅保留本地Date部分?(no字符串解析或操作)

将序列化的IasyncESYS上传到Azure Blob存储的最佳方法是什么

我可以将Expressc操作设置为在另一个Expressc操作完成后自动发生吗?

无法使用并行库并行化我的代码

为什么我在PuppeteerSharp中运行StealthPlugin时会出现错误?

始终保留数组中的最后N个值,丢弃最老的

C#中使用BouncyCastle计算CMac

Unity 2D自顶向下弓旋转

C#DateTime.ToString在ubuntu和centos中返回不同的结果

使用Audit.EntityFramework,我如何将外键的值设置为相关实体上的属性?

在允许溢出的情况下将小数转换为长

为什么C#认为这个非托管 struct 有一个重叠

是否有必要在ASP.NET Core中注册可传递依赖项?

在DoubleClick上交换DataGridViewImageColumn的图像和工具提示

在Docker容器中运行API项目时,无法本地浏览到index.html

我可以查看我们向应用程序洞察发送了多少数据吗?

岛屿和框架中的自定义控件库.Navigate-AccessViolationException

在同一个捕获中可以有多种类型的异常吗?

从MudAutoComplete打开对话框,列表仍然可见

SignalR跨域