суббота, 3 сентября 2016 г.

Как найти исключение, которого нет

Привет! Может случиться так, что ваша система работает у заказчика и периодически ведет себя некорректно из-за логических ошибок, но аварийно не завершается. Одной из причин такого поведения может служить пресловутый catch по всем типам исключений с дальнейшим проглатыванием. Как быть в таком случае? Сейчас я расскажу.

Ситуация особенно усугубляется, если такое поведение не получается воспроизвести локально и поотлаживаться в Visual Studio. В этом случае последней надеждой является исследование дампа памяти процесса. Но его надо снять правильно. Нас интересует дамп не в любой момент времени, а именно в момент возникновения исключений. Получить его можно с помощью утилиты ProcDump от известного Марка Руссиновича. Нас интересует параметр –e 1, который указывает, что дамп памяти должен быть снять в момент возникновения исключения и –ma, указывающий, что нужно снять дамп со всей памяти процесса.

procdump.exe -ma -e 1 16036 (последнее число - ID процесса)

Затем открываем дамп в WinDbg нажатием комбинации Ctrl + D, и в окне команд загружаем Sos. Sos – это расширение WidDbg, которое позволяет в удобном виде получать низкоуровневую информацию из мира .Net в анализируемом процессе или дампе памяти. Подробней о Sos можно почитать тут

.loadby sos clr

Команда !threads выведет на экран полный список потоков процесса.


В последнем столбце можно увидеть тип исключения, которое возникло в каждом потоке. В нашем случае это DevideByZeroException в потоке 0 (внутренний идентификатор в отладчике). Переключаемся на него командой ~0s и вызываем команду !ClrStack для просмотра стека потока.


Теперь известно место, где произошло исключение. В нашем случае это метод RaiseAndHandleException, Также можно подробней изучить возникшее исключение с помощью команды !pe.


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

Тестовый пример, с помощью которого можно опробовать все описанное, можно взять тут.

Много полезной информации по отладке .Net и использовании WinDbg и Sos можно найти в следующих источниках:
  • Advanced .NET Debugging (Amazon)
  • Debugging Application for Microsoft .NET and Microsoft Windows (Amazon)
  • Pro .NET Performance: Optimize Your C# Application (Amazon)

Комментариев нет:

Отправить комментарий