Как найти источник исключения StackOverflowException в моем приложении

У меня есть StackOverFlow, встречающийся где-то в моем приложении, - и я пытаюсь выяснить способы его отслеживания.

Мои журналы событий показывают сбой каждый день или около того со следующей информацией:

Неверное имя приложения: MyApp.exe, версия: 1.0.0.0, отметка времени: 0x522e8317

Неверное имя модуля: clr.dll, версия: 4.0.30319.18047, отметка времени: 0x515530ce

Код исключения: 0xc00000fd

Смещение ошибки: 0x000000000000c657

Идентификатор процесса отказа: 0x117fc

Время сбоя приложения: 0x01ceadf607b184d2

Неисправность пути приложения: C:\Users\Administrator\Desktop\MyApp.exe

Отказоустойчивый путь модуля: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

Идентификатор отчета: d52424aa-1a16-11e3-bc4b-002590a4ec55

Я читал, что 0xc00000fd - это переполнение стека, но я не уверен, где это может произойти (очень большая база кода) и как его отслеживать. Любые идеи?

Ответы

Ответ 1

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

WinDbg - отладчик для Windows, хорошо подходит для отладки управляемого и неуправляемого кода. Это также отлично подходит для изучения аварийных дампов. Начните с примера программы.

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

    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
    static int IWillStackOverflow(int i)
    {
        return IWillStackOverflow(i + 1);
    }
}

Это довольно надуманный пример, но пусть рулон с ним. Он действительно переполняет стек, и не обеспечивает стек. Здесь вы найдете WinDbg. Сначала вам нужно установить его, который является частью инструментов отладки в Windows SDK. Есть две версии: x64 и x86. Вы хотите запустить ту, которая соответствует битности вашего приложения.

В WinDbg используйте File → Open Executable и запустите исполняемый файл с помощью WinDbg. Отладчик будет разорваться, как только ваше приложение загрузится, вы можете использовать команду g для перехода и использования вашего приложения, пока не получите исключение StackOverflowException. Прежде чем вы это сделаете, убедитесь, что ваши символы верны - обычно выполняется .symfix+, и вы можете пойти.

Когда вы получите свое StackOverflowException, отладчик сломает поток, который вызвал исключение, и сообщение будет примерно таким:

(cc0.b00): переполнение стека - код c00000fd (первый шанс)

Теперь мы можем загрузить управляемые отладочные расширения с помощью этой команды (я предполагаю, что вы используете .NET Framework 4.0 или 4.5 здесь):

.loadby sos clr

И вызов !clrstack. В этом примере вывод:

000000d440c76040 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c76080 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c760c0 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
..Repeat thousands of times..

Итак, у нас есть наш управляемый стек во время исключения StackOverflowException.

Если ваше приложение не делает StackOverflow очень легко, вы можете настроить ADPlus, чтобы взять дамп памяти вашего приложения во время исключения StackOverflowException, ADPlus - еще один инструмент большого молотка, но он эффективен. Сначала вам нужна конфигурация для ADPlus, вот пример:

<ADPlus> 
   <!-- Add log entry, log faulting thread stack and dump full on first chance StackOverflow --> 
<Exceptions> 
     <Config> 
        <!-- Use sov for Qaru exception --> 
       <Code> sov </Code> 
       <Actions1> Log;Stack;FullDump </Actions1> 
       <!-- Depending on what you intend - either stop the debugger (Q or QQ) or continue unhandled (GN) --> 
       <ReturnAction1> GN </ReturnAction1> 
     < Config> 
  </Exceptions> 
</ADPlus>

Этот пример конфигурации был первоначально опубликован пользователем jaskis на форумах MSDN: http://blogs.msdn.com/b/jaskis/archive/2010/08/11/cwa-ends-up-with-blank-screen-on-browser-on-iis-7.aspx Затем используйте командную строку, чтобы запустить приложение с конфигурацией.


Это просто пример, WinDbg - очень мощный инструмент, хотя он имеет немного кривой обучения. В Интернете есть много хороших ресурсов, чтобы их повесить. Tess Ferrandez содержит много статей в своем блоге, которые охватывают WinDbg и управляемые расширения отладки.

Ответ 2

Это уже ответили, но я искал лучший ответ, чем WinDbg на зараженной машине, поскольку это происходит только на машинах производственного сервера для меня, где я не хочу устанавливать WinDbg. Я нашел эту статью, где он относится к загружаемому инструменту от Microsoft, который позволяет вам настроить на основе кода исключения код, как система должны реагировать на различные исключения. Это позволит (надеюсь) разрешить отладку на другой машине, чем на производственной машине:

Эта утилита DebugDiag может быть сконфигурирована для создания дампа сбоя при возникновении StackOverflowException. Скачайте здесь.