Table of Contents

Диагностика вылета программы без дампа по журналу событий Windows

Проблема

Приложение неожиданно завершается (вылетает) без предложения отправить отчет об ошибке разработчикам ЛЭРС УЧЕТ, отображая при этом стандартное окно с надписью "Прекращена работа программы ЛЭРС УЧЕТ - XXX".

Решение

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

В этом случае ОС делает запись в журнале событий Windows "Приложение" с источником "Windows Error Reporting" и уровнем "Сведения".

Содержимое записи выглядит примерно следующим образом:

P1: lers.client.exe // Имя исполняемого файла
P2: 3.8.0.30800 // Версия сборки исполняемого файла (P1)
P3: 53842d91// Дата и время создания исполняемого файла (P1)
P4: Lers.Client // Сборка, в которой произошло исключение
P5: 3.8.0.30800 // Версия сборки (P4), в которой произошло исключение
P6: 53842d91 // Дата и время создания сборки (P4)
P7: 6e // Маркер метода, в котором произошло исключение
P8: b // Смещение IL в методе (P7)
P9: System.InvalidOperationException // Тип исключения

С помощью этой информации можно определить точное место, в котором произошло исключение. Для этого понадобится лишь такая же сборка (P4) нужной версии (P5) и отладчик WinDbg.

Определение места возникновения исключения

  1. Запустите отладчик WinDbg нужной разрядности (32/64 bit). Через пункт меню File->Open Executable откройте исполняемый файл (P1) точно такой же версии как (P2). Если исключение произошло не в исполняемом файле (P1), то необходимо удостовериться, что в процесс будет загружена сборка (P4) нужной версии (P5).
  2. Нажмите пункт меню Debug->Go, чтобы запустился процесс. Далее необходимо заставить CLR загрузить сборку (P4) в память, т. е. выполнить действия, которые приведут в вызову какого-либо метода, содержащегося в сборке.
  3. Загрузите библиотеку SOS для отладки приложений .NET. Чтобы загрузилась правильная библиотека, необходимо использовать команду .loadby, иначе команда !Token2EE может не работать и выдавать ошибку “offset not exist for m_firstBlock. Is the framework loaded yet?”: .loadby sos clr
  4. Теперь необходимо получить описание метода. Для этого необходимо сначала сложить число 0x06000000 и параметр (P7): 0x0600006e. И после этого выполнить команду: !Token2EE lers.client.exe 0600006e
Внимание

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

Результат выполнения команды:

   Module:      00202eac
   Assembly:   Lers.Client.exe
   Token:       0600006e
   MethodDesc:  006313d0 // Адрес описания метода
   Name:        Lers.MainForm.<barButtonMaps_ItemClick>b__0(System.Object) // Полное название метода,
  1. На последнем шаге определяем точное место в методе, где произошло исключение. Для этого дизассемблируем код метода с помощью команды: !dumpil 006313d0 Результат выполнения команды:
   ilAddr = 009e322f 
   IL_0000: nop 
   IL_0001: ldstr "test" 
   IL_0006: newobj System.InvalidOperationException::.ctor 
   IL_000b: throw

С помощью параметра (P8) = b в IL-коде находим нужную строку IL_000b. Это и есть точное место, где произошло исключение.

Список источников