无法正确单步执行静态构造函数中的代码(VS2019、C#、.NET 4.7.2)

Posted

技术标签:

【中文标题】无法正确单步执行静态构造函数中的代码(VS2019、C#、.NET 4.7.2)【英文标题】:Unable to properly step through code in static constructor (VS2019, C#, .NET 4.7.2) 【发布时间】:2021-07-18 21:18:51 【问题描述】:

我正在尝试在中断模式下单步执行静态构造函数的代码。

项目是 C#/.NET 4.7.2/64-bit/WinForms。 Visual Studio 版本为 2019 16.9.4 Community。

Visual Studio 在到达静态构造函数中设置的断点时会正确中断。然后我可以使用“Step Into”命令 (F11) 单步执行代码。如您所见,静态构造函数调用了一个静态方法来完成繁重的工作。

代码包含一个应该迭代 10 次的循环。我应该能够逐步完成所有迭代。相反,在第一次迭代之后,调试突然跳到——或“恢复”——在稍后的某个时间点,回到调用类(或更准确地说,是触发 CLR 执行静态构造函数的类)。所以我无法逐步完成剩下的 9 次迭代。

我确信所有的迭代都确实被执行了,因为我添加了一些调试代码来在每次执行 finally 块时打印一些东西。但是,我很沮丧,因为我无法单步执行代码。看起来像是一种可笑的 VS 错误,因为在调试时能够单步执行代码是一件非常基本的事情。

因为这个问题很难描述清楚,所以我创建了一个动画 GIF 来直观地显示调试会话:

我已经在网上广泛搜索,但找不到其他人报告我在这里遇到的问题。这让我想知道我是否做错了什么(例如,我需要调整一些调试器设置吗?)。非常感谢任何帮助或见解。

更新

我无法在 32 位调试版本中重现该问题。该问题(到目前为止)仅存在于 64 位调试版本中。

如何复制

我做了一个小型演示项目。随意下载并尝试自己调试。当断点被命中时,使用 F11 单步执行代码。看看你是否可以通过循环 10 次;-)

Debug Test Project (VS2019)

最后,如果我将构建配置从 x64 更改为 Any CPU,问题就会消失。所以它可能只是一个 64 位的问题。

try/finally 块似乎确实揭示了这个问题。我不确定还有哪些其他模式也可能揭示这个问题。

已提交错误报告

https://developercommunity.visualstudio.com/t/The-debugger-does-not-step-through-a-met/1407274

【问题讨论】:

更新:如果我将繁重的代码直接移动到静态构造函数中,那么我可以单步执行所有迭代但是我无法单步执行finally 块 - 调试器完全跳过它(尽管它确实执行了)。这是怎么回事?! 如果你在循环中放置一个断点会发生什么?它会被击中 10 次吗? @ekke 是的。如果我在循环中设置断点,断点会命中 10 次。但是,如果我将断点放在 try 语句处,那么当它命中时,我可以单步执行代码,但调试器不允许我单步执行 varMarshall.StructureToPtr 语句 - 它会跳过每个迭代!好奇怪。 @ekke 重要更新 - 我无法在 32 位调试版本中重现此问题。该问题(到目前为止)仅存在于 64 位调试版本中。 这已成为 Dotnet 运行时存储库中的一个 github 问题:github.com/dotnet/runtime/issues/52328 【参考方案1】:

这是 .NET 运行时中的一个错误。您可以在此处跟踪错误:

https://github.com/dotnet/runtime/issues/52328

【讨论】:

禁用仅我的代码选项以避免它

以上是关于无法正确单步执行静态构造函数中的代码(VS2019、C#、.NET 4.7.2)的主要内容,如果未能解决你的问题,请参考以下文章

从 python 调试 VS2010 中的 c++ dll

VS 调试

VS2019 C++动态链接库的创建使用

Java子父类间静态代码块非静态代码块构造方法的执行顺序

关于软件构造最后一部份(PPT212)的复习

调用堆栈中的“[轻量级函数]”