Поведение StackFrame.GetFileLineNumber () зависит от платформы сборки и флагов оптимизации. - PullRequest
1 голос
/ 23 февраля 2011

Я пытаюсь понять проблему, и хотя я много читал, я не могу найти никаких ресурсов, объясняющих эту странную комбинацию.

После нескольких экспериментов я обнаружил, чтокомбинации включения / выключения оптимизации компилятора и сборки для платформы 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

1 Ответ

0 голосов
/ 23 февраля 2011

Когда вы включаете оптимизацию, вы говорите JITter вести себя по-другому.

Некоторые вызовы функций объединяются с другими для сохранения кадра стека, циклы развертываются и т. Д. Структура MSIL может / изменится радикально.

Сбой может быть из-за того, что вызов функции был свернут, а кадр стека, который вы пытаетесь извлечь, не существует. Переход от строки 10 к 12, очевидно, происходит из-за того, что компилятор перетасовывает инструкции, чтобы получить лучший результат.

Только мои 0,02 доллара:)

...