1

私は問題を理解しようとしていますが、たくさん読みましたが、この奇妙な組み合わせを説明するリソースを見つけることができないようです.

少し実験した後、コンパイラの最適化のオン/オフを設定し、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
4

1 に答える 1

0

最適化をオンにすると、JITter に異なる動作をさせることになります。

一部の関数呼び出しは、スタック フレームを保存するために他の関数呼び出しにマージされ、ループはアンロールされます。MSIL の構造は大幅に変更される可能性があります。

クラッシュは、関数呼び出しが折りたたまれ、抽出しようとしているスタック フレームが存在しないことが原因である可能性があります。10 行目から 12 行目へのジャンプは、コンパイラが最適なパフォーマンスを得るために命令をシャッフルしているためです。

ちょうど私の$ 0.02 :)

于 2011-02-23T06:29:02.747 に答える