gpt4 book ai didi

c# - 我认为我的团队在 64 位编译器中发现了一个错误,其他人可以确认或告诉我为什么这是正确的吗?

转载 作者:可可西里 更新时间:2023-11-01 08:02:57 26 4
gpt4 key购买 nike

我有一个关于此可能错误的简单无尘室示例。

   static void Main(string[] args)
{
bool MyFalse = false;

if (MyFalse)
{
throw new Exception();
}
try
{
int i = 0;
}
catch (Exception e)
{
Console.Write(e);
}

Console.Read();
}

如果在 x64 或 AnyCPU 中编译(当 prefer 32bit 在 VS2012 中设置为 false 时)如果你在 if block 中放置断点,它总是会被命中。

我们在 VS2012、VS2010 和 VS2008 中尝试过,它们在 64 位编译时都触发了 if block ,但在 32 位中它不会触发 if block 。

我们查看了 32 位和 64 位版本的 IL,它们看起来是一样的。

我们在生产代码中发现了这一点,因为正在运行 if block 并且无论 bool 变量的值是多少都会抛出异常,尽管在简单的示例中我们似乎无法抛出异常,它是发生在生产代码中。

由于它发生在生产代码中,因此它不仅仅是调试器问题。

非常奇怪的行为,但似乎并没有实际运行 if block 中的任何代码。开发人员立即假设这是他看到的异常。

(所有调试处于 Debug模式 - 生产处于发布状态)

如果抛出被注释掉 - 未到达 if block 。

最佳答案

好的,我明白了。这在 64 位调试器的调试版本中确实出错了。关键是在 if() 语句上准确设置断点,然后开始单步执行。 看起来 throw 语句正在执行。但实际上并没有发生,实际的代码执行是正确的。

要查看发生了什么,请让它进入 throw 语句行。然后使用Debug + Disassembly 来查看它实际所在的位置。在我的机器上它看起来像这样:

       if (MyFalse)
00000040 movzx ecx,byte ptr [rbp+8]
00000044 xor eax,eax
00000046 test ecx,ecx
00000048 sete al
0000004b mov dword ptr [rbp+1Ch],eax
0000004e movzx eax,byte ptr [rbp+1Ch]
00000052 mov byte ptr [rbp+18h],al
00000055 movzx eax,byte ptr [rbp+18h]
00000059 test eax,eax
0000005b jne 0000000000000088 // <=== Note this jump
{
0000005d nop
throw new Exception();
0000005e lea rcx,[5B848928h]
00000065 call 000000005F65E9E0
0000006a mov qword ptr [rbp+20h],rax
0000006e mov rax,qword ptr [rbp+20h]
00000072 mov qword ptr [rbp+28h],rax
00000076 mov rcx,qword ptr [rbp+28h]
0000007a call 000000005BE4A5D0
0000007f mov rcx,qword ptr [rbp+28h]
00000083 call 000000005F73E36C
00000088 nop // <=== yellow arrow here
}
try
{
00000089 nop
int i = 0;

您甚至可以从调试器将机器代码指令与 C# 语句分组的方式中看出这一点。请注意调试器如何混淆地址 0088 处的 NOP。它认为它属于复合 if() 语句。所以它将黄色突出显示放在 block 内。但是程序实际上已经在地址 005b 处跳转并跳过了 throw 语句(地址 005e 到 0083)。

不太确定该将责任归咎于此,不能责怪 C# 编译器或 PDB 文件,因为它可以在 32 位模式下正常运行。它闻起来像抖动问题,值得注意的是 x86 抖动不会生成 NOP 指令。您还可以假设抖动应该生成了跳转到地址 0089 的 JNE 指令。这些只是猜测,您可以在 connect.microsoft.com 上找到真正的答案

请记住这个怪癖,直到您收到回复或我们都在服务包中获得更新。该代码实际上执行正确,因此您只会感到轻微的困惑。

关于c# - 我认为我的团队在 64 位编译器中发现了一个错误,其他人可以确认或告诉我为什么这是正确的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16365757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com