Почему .NET не регистрирует трассировку стека для исключений StackOverflow? - PullRequest
5 голосов
/ 20 сентября 2011

Если я напишу это:

class Program
{
    static void Main(string[] args)
    {
        throw new Exception("lol");
    }
}

и запусту exe из командной строки, я получу две записи в моем журнале событий.Одна из них - ошибка приложения, которая говорит о том, что было необработанное исключение, а другая содержит трассировку стека с источником как .NET Runtime.

Если я напишу это:

class Program
{
    static void Main(string[] args)
    {
        Recurse4Evr();
    }

    static void Recurse4Evr()
    {
        Recurse4Evr();
    }
}

Я толькополучить одну запись в моем журнале событий, в которой говорится об ошибке приложения и исключении переполнения стека.Второй записи с трассировкой стека нет, поэтому она в принципе бесполезна.

Почему трассировка стека также не записывается в журнал?Если я установлю DebugDiag и прикреплю его к своему процессу, а затем произойдет переполнение стека, DebugDiag сможет записать трассировку стека.Очевидно, что трассировка стека в некотором роде доступна внешнему миру.Если среда выполнения завершает процесс, потому что он обнаружил переполнение стека, он также знает, что такое стек.

В больших приложениях, которые имеют много сложных взаимодействий, часто невозможно воссоздать условия, которые привели к переполнению стека.В этой ситуации трассировка стека является единственным способом выяснить, что произошло.Почему Microsoft решила, что не важно регистрировать эту информацию?Было ли законное дизайнерское решение, которое не очевидно?

Ответы [ 2 ]

1 голос
/ 20 сентября 2011

Переполнение стека считается невосстанавливаемой ситуацией и для такого времени выполнения убивает процесс.

Подводя итог:

от Damien_The_Unbeliever

Со страницы MSDN на StackOverflowException s:

В предыдущих версиях .NET Framework ваше приложение могло перехватывать объект StackOverflowException (например, для восстановления после неограниченной рекурсии). Однако такая практика в настоящее время не приветствуется, поскольку требуется значительный дополнительный код, чтобы надежно перехватить исключение переполнения стека и продолжить выполнение программы.

Начиная с .NET Framework версии 2.0, объект StackOverflowException не может быть перехвачен блоком try-catch, и соответствующий процесс завершается по умолчанию. Следовательно, пользователям рекомендуется писать свой код для обнаружения и предотвращения переполнения стека. Например, если ваше приложение зависит от рекурсии, используйте счетчик или условие состояния для завершения рекурсивного цикла. Обратите внимание, что приложение, в котором размещается общеязыковая среда выполнения (CLR), может указать, что CLR выгружает домен приложения, где происходит исключение переполнения стека, и позволяет соответствующему процессу продолжаться. Для получения дополнительной информации см. Интерфейс ICLRPolicyManager и хостинг общеязыковой среды выполнения.


от JaredPar

Начиная с 2.0, исключение StackOverflow может быть обнаружено только при следующих обстоятельствах.

  1. CLR запускается в размещенной среде, где хост специально разрешает обработку исключений StackOverflow
  2. Исключение stackoverflow генерируется кодом пользователя, а не из-за фактической ситуации переполнения стека ( Reference )
0 голосов
/ 08 октября 2011

Это, по-видимому, невозможно.Если вам нужна трассировка стека, чтобы вы могли найти вредоносный код, который убил ваше приложение, вам нужно подключить сторонний инструмент, такой как DebugDiag или AdsPlus.Удачи, в основном нет документации для этих инструментов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...