В процессе работы, приложение .NET может столкнуться с исключением, которое оно по тем или иным причинам не обрабатывает. В этом случае вдело вмешивается среда CLR. Принимая пропущенное приложением исключение, CLR обрабатывает его и выдаёт пользователю на экран монитора информационное окно .NET Runtime 2.0 Error Reporting с сообщением о возникшей у приложения проблеме. После закрытия окна, CLR завершает работу некорректного приложения. При этом описание и параметры возникшего исключения дублируются CLR в событийном логе Windows в разделе приложений. Возникает естественный вопрос - а можно ли по зафиксированной в логе информации понять в каком месте приложения возникла исключительная ситуация, с тем чтобы внести необходимые исправления? Ответ Да. Посмотрим как это можно сделать.
Для примера приведу один такой эксепшн
Тип события: Ошибка
Источник события: .NET Runtime 2.0 Error Reporting
Категория события: Отсутствует
Код события: 5000
Дата: 01.10.2014
Время: 19:34:28
Пользователь: Н/Д
Компьютер: xxx
Описание:
EventType clr20r3, P1 yyy.exe, P2 1.0.0.0, P3 542bd373, P4 zzz, P5 1.0.0.0, P6 542bd372, P7 1b7, P8 1, P9 system.nullreferenceexception, P10 NIL.
В поле "Описание" содержится важная информация. В частности интересны следующие параметры:
P1 yyy.exe -- программа в которой возникло исключение;
P4 zzz -- сборка программы (namespace);
P7 1b7 -- метод получивший исключение;
P8 1 -- смещение от начала метода;
P9 system.nullreferenceexception -- тип исключения (отсутствует ссылка на экземпляр объекта).
Таким образом, есть вся информация чтобы найти место где возникло исключение. Параметры P1, P4, P9 не вызывают никаких затруднений при анализе ошибки, так как фигурирующие в них значения имеют формат строки, чего не скажешь о параметре P7. Нам нужно имя метода, а не его кодовое значение. Займёмся этим.
Нам потребуется средство - Дизассемблер IL. Он входит в состав пакета Microsoft Windows SDK Tools. Запускаем и открываем файл zzz.dll. Далее необходимо открыть окно с метаданными указанной сборки. Для этого выбираем последовательно пункты меню Вид>Метаданные>Показать!. В окне метаданных ищем код из параметра P7 начинающийся с 0x06, или в моём случае 060001b7. Этому коду соответствует MethodName: RunMethod (060001B7). А зная метод в котором возникло непредвиденное исключение, и имея под рукой его исходник, уже гораздо легче найти место возникновения ошибки.
Удачи в отладке кода!
P.S. Более полный список параметров:
- P1. Exe file name
- P2. Exe file assembly version number
- P3. Exe file time stamp
- P4. Exe file full assembly name
- P5. Faulting assembly version
- P6. Faulting assembly time stamp
- P7. Faulting assembly method def
- P8. Faulting method IL offset within the faulting method
- P9. Exception type