【问题标题】:Debugger stepping into if() block where condition is false调试器进入条件为假的 if() 块
【发布时间】:2015-02-17 12:04:31
【问题描述】:

鉴于这段代码:

class Program
{
    private static bool IsAdmin = true;

    static void  Main(string[] args)
    {
        if (!IsAdmin)
        {
            throw new Exception();
        }

        try
        {
            var x = 2342342;
            var y = 123132;
        }
        catch (Exception)
        {
            throw;
        }
    }
}

鉴于this.IsAdmin 的结果为真 - 我希望调试器不会输入该 if 语句。实际上它确实 - 它跨过投掷但实际上并没有投掷!

现在,只有当您在 Visual Studio 2013 上的 if 语句后跟 try/catch 块中出现异常时,才会发生这种情况,目标是 .NET Framework 4,64 位,未选中“首选 32 位”。

我已经与不同机器上的同事确认了这种奇怪之处。单步执行以下代码,调试器似乎会进入 if 分支,但不会引发异常:

我处于调试模式,我已尝试多次编译和清理项目。

谁能解释为什么会这样?

【问题讨论】:

  • 很好的发现,调试器对 IL 做了各种疯狂的事情,可能是优化前变量重新排序之类的

标签: c#


【解决方案1】:

这是一个由 x64 抖动引起的已知问题,它偶尔会生成错误的调试行号信息。当语句导致生成额外的 NOP 指令以对齐代码时,它可能会出错。第一个 NOP 成为行号,而不是 NOP 之后的指令。这个字节在几个地方,比如一个简单的 if() 测试和使用 ?? 之后的 throw 语句。具有简单标量操作数的运算符。这些对齐 NOP 也是中止线程如此危险的原因,在 this post 中进行了描述。

最简单的解决方法是项目 + 属性,构建选项卡,勾选“首选 32 位”选项(如果可用),否则将平台目标设置为 x86。请注意实际上并没有出错,而调试器建议将要执行 throw 语句,您的程序实际上并没有引发异常。

它正在处理中,x64 抖动被彻底重写,一个名为 RyuJIT 的项目。它将在 VS2015 中发布,目前处于预览阶段。

【讨论】:

  • 谢谢 - 唯一的问题是我花了这么长时间试图找出我的代码不好的地方 - 你不认为 MS 的东西会是罪魁祸首!
  • 谢谢。他们到底在想什么。
  • PS...今天遇到这个问题...在VS2015中。 :(
【解决方案2】:

查看this 链接。这是 Visual Studio 的某些版本和 .NET 框架版本中的一个已知错误。它完全无害,您只需要忍受即可。

【讨论】:

  • 我的理智保持在机智,一切都很好!
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多