Обработчик необработанных исключений C ++ Win32 - PullRequest
3 голосов
/ 20 марта 2010

в настоящее время я использовал SetUnhandledExceptionFilter () , чтобы обеспечить обратный вызов для получения информации, когда произошло необработанное исключение, этот обратный вызов предоставит мне EXCEPTION_RECORD , который обеспечивает ExceptionAddress.

[1] что на самом деле есть ExceptionAddress? это адрес функции / кода, который дает исключение, или адрес памяти, к которому пыталась получить доступ какая-то функция?

[2] есть ли лучший механизм, который мог бы дать мне лучшую информацию, когда произошло необработанное исключение? (Я не могу использовать режим отладки или добавлять какой-либо код, который влияет на производительность во время выполнения, поскольку сбой происходит редко и только при сборке релиза, когда код выполняется максимально быстро)

[3] могу ли я получить несколько адресов стека вызовов при возникновении необработанного исключения.

[4] предположим, что ExceptionAddress имеет адрес A, и у меня есть DLL X, загруженная и выполняемая по базовому адресу A-x, и некоторая другая DLL Y в A+y, хорошо ли предположить, что сбой был ВЕРОЯТНО вызвано кодом на DLL X?

Ответы [ 3 ]

5 голосов
/ 20 марта 2010

(1) ExceptionAddress - это адрес кода, вызвавшего исключение. В случае ошибки нарушения доступа (0xC0000005) один из дополнительных аргументов записи исключения содержит адрес, с которого была предпринята попытка чтения или записи, а другой аргумент сообщает, было ли это чтение или запись. Это задокументировано в ссылке, которую вы указали в вопросе.

(2) нет. Кроме того, добавление отладочной информации в сборку релиза не влияет на производительность. Вы можете убедиться в этом и убедиться сами.

(3) dbghelp.dll предоставляет полную библиотеку для расследования сбоев. среди атеров есть StackWalk64, который позволяет получить полный стек аварии.

(4) вызов GetModuleHandleEx с аргументом ExceptionAddress даст вам дескриптор dll, в котором находится нарушающий код. Что касается вопроса о том, какой DLL CAUSED сбой, это зависит от вашего определения " CAUSED ". Авария, происходящая в одной dll, может быть результатом ошибки в совершенно другой и не связанной dll.

0 голосов
/ 20 марта 2010

Кроме того, не прямой ответ на ваш вопрос, но я думаю, что это может помочь вам:

http://www.codeproject.com/KB/applications/blackbox.aspx

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

Это сработало хорошо для меня.

Существует также улучшенная версия с именем "Черный ящик исправлен". Хотя сейчас не могу найти сайт.

0 голосов
/ 20 марта 2010

Не прямой ответ на ваш вопрос, но, возможно, это то, что вам нужно: http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx

Посмертная отладка - это способ найти место исключения, когда программа выполняется в сборке Release на клиентском компьютере.

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