2010-03-20 8 views
3

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

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

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

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

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

ответ

5

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

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

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

(4) вызов GetModuleHandleEx с ExceptionAddress в качестве аргумента даст вам дескриптор dll, в котором находится код нарушения. Что касается вопроса о том, какая ошибка, это зависит от вашего определения «ПРИЧИНА». Авария, возникающая в одной dll, может быть результатом ошибки в совершенно другой и несвязанной dll.

+0

(1) OK (2) хорошо в моем случае, если я отлаживаю информацию о выпуске сборки, авария никогда не происходила. (3) спасибо, пожалуйста, приведите несколько примеров, как это использовать? (4) Я попробую это. спасибо – uray

+0

Вот базовое учебное пособие, которое, как представляется, показывает, как его использовать, любезно предоставлено google: http://jpassing.com/2008/03/12/walking-the-stack-of-the-current-thread/ – shoosh

0

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

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

+0

Да, я тоже использовал это, но нужно потратить много времени, чтобы прочитать minidump на стороне разработчика, мне нужно быстро узнать, как/где произошло исключение. – uray

0

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

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

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

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

Существует также улучшенная версия под названием «Blackbox revision». Не могу найти сайт прямо сейчас.