StackFrame.GetFileLineNumber() 行为因程序集平台和优化标志而异

发布于 2024-10-19 07:04:43 字数 1695 浏览 13 评论 0原文

我正在尝试理解一个问题,尽管我读了很多书,但我似乎找不到任何资源来解释这种奇怪的组合。

经过一番实验后,我发现设置编译器优化开/关和为 AnyCPU/x86 平台构建的组合会改变 StackFrame.GetFileLineNumber() 的行为,

我不明白为什么我得到以下结果(在我的 x64 系统)

  Optimisations     | Platform      | Line Number Reported  | Result
 -------------------|---------------|-----------------------|----------
  off               | anycpu        | 10                    | Correct
  off               | x86           | 10                    | Correct
  on                | anycpu        | APPCRASH              | WTF?
  on                | x86           | 12                    | WTF?

下面的代码重现了该问题。

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            GetLineNumberOfThisCall();

            Console.WriteLine("\r\nPress any key to exit...");
            Console.ReadKey();
        }

        private static void GetLineNumberOfThisCall()
        {
            var stackTrace = new StackTrace(true);
            var callingFrame = stackTrace.GetFrame(1);

            Console.WriteLine("The call to the stack-walking method was found on line: {0}", callingFrame.GetFileLineNumber());
        }
    }
}

如果将上述代码保存为code.cs,则使用以下脚本创建一个批处理文件,它将编译程序集以轻松解决问题:

csc /t:exe /debug+ /out:anycpu-optimisation-on.exe /platform:anycpu /optimize+ code.cs
csc /t:exe /debug+ /out:anycpu-optimisation-off.exe /platform:anycpu /optimize- code.cs
csc /t:exe /debug+ /out:x86-optimisation-on.exe /platform:x86 /optimize+ code.cs
csc /t:exe /debug+ /out:x86-optimisation-off.exe /platform:x86 /optimize- code.cs

i'm trying to understand a problem and although I've read a lot, I can't seem to find any resources explaining this odd combination.

After a bit of experimentation I've found that combinations of setting compiler optimisations on/off and building for the AnyCPU/x86 platform changes the behaviour of StackFrame.GetFileLineNumber()

I don't understand why i'm getting the following results (on my x64 system)

  Optimisations     | Platform      | Line Number Reported  | Result
 -------------------|---------------|-----------------------|----------
  off               | anycpu        | 10                    | Correct
  off               | x86           | 10                    | Correct
  on                | anycpu        | APPCRASH              | WTF?
  on                | x86           | 12                    | WTF?

The code below reproduces the problem.

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            GetLineNumberOfThisCall();

            Console.WriteLine("\r\nPress any key to exit...");
            Console.ReadKey();
        }

        private static void GetLineNumberOfThisCall()
        {
            var stackTrace = new StackTrace(true);
            var callingFrame = stackTrace.GetFrame(1);

            Console.WriteLine("The call to the stack-walking method was found on line: {0}", callingFrame.GetFileLineNumber());
        }
    }
}

if you save the above code as code.cs create a batch file with the following script, it will compile assemblies to easily repo to the problem:

csc /t:exe /debug+ /out:anycpu-optimisation-on.exe /platform:anycpu /optimize+ code.cs
csc /t:exe /debug+ /out:anycpu-optimisation-off.exe /platform:anycpu /optimize- code.cs
csc /t:exe /debug+ /out:x86-optimisation-on.exe /platform:x86 /optimize+ code.cs
csc /t:exe /debug+ /out:x86-optimisation-off.exe /platform:x86 /optimize- code.cs

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

血之狂魔 2024-10-26 07:04:43

当您打开优化时,您就是在告诉 JITter 以不同的方式表现。

一些函数调用被合并到其他函数中以保存堆栈帧、展开循环等。MSIL 的结构可以/将会发生巨大的变化。

崩溃可能是因为函数调用已折叠并且您尝试提取的堆栈帧不存在。从第 10 行跳转到第 12 行显然是由于编译器为了获得最佳性能而对指令进行了改组。

只是我的 0.02 美元:)

When you turn on optimisations you're telling the JITter to behave differently.

Some function calls are merged into others to save a stack frame, loops are unrolled, etc. The structure of the MSIL can/will change drastically.

The crash could be because the function call was collapsed and the stack frame your trying to extract doesn't exist. The jump from line 10 to 12 is obviously due to the compiler shuffling around instructions to get the best perf.

Just my $0.02 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文