Как получить информацию об исключении переполнения буфера в смешанном приложении?

Во всех приложениях WPF, которые я разрабатываю, есть глобальный обработчик исключений, подписанный на AppDomain. CurrentDomain.UnhandledException , который регистрирует все, что может найти, а затем показывает диалоговое окно, предлагающее пользователю связаться с автором, где находится файл журнала и т. Д.Это работает очень хорошо, и мы с клиентами очень им довольны, потому что это позволяет быстро устранять проблемы.

Однако во время разработки смешанного приложения WPF / C # / CLI / C ++ иногда возникают сбои приложения, которые не попадают в вышеупомянутый обработчик исключений. Вместо этого появляется стандартное диалоговое окно Windows с сообщением «XXX перестала работать». В деталях он показывает, например,

 Problem Event Name: BEX
 Application Name:   XXX.exe
 Fault Module Name:  clr.dll
 ...

Это чаще всего происходит при обратном вызове управляемой функции из неуправляемого кода и когда эта функция обновляет экран. Мне не потребовалось много времени, чтобы выяснить основную причину проблемы, но только потому, что я могу воспроизвести сбой на своей машине и подключить отладчик: во всех случаях собственный поток все еще находился в точке вызова указателя функции на управляемый делегат, который вызывает непосредственно код C # / WPF.

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

Вопрос: что я могу сделать, чтобы получить дополнительную информацию о подобных сбоях? Есть ли способ получить такое исключение, как этот вызов специального обработчика ошибок? Или получить дамп процесса? При загрузке символов для msvcr100_clr0004.dll и clr.dll (загружается в поток, в котором происходит прерывание), стек вызовов выглядит следующим образом:

msvcr100_clr0400.dll!__crt_debugger_hook()  
clr.dll!___report_gsfailure()  + 0xeb bytes 
clr.dll!_DoJITFailFast@0()  + 0x8 bytes 
clr.dll!CrawlFrame::CheckGSCookies()  + 0x2c3b72 bytes  

Могу ли я каким-то образом подключить некоторый собственный код C ++ к __crt_debugger_hook () (например, для записи минидампа)? Это приводит меня к дополнительному вопросу: как CheckGSCookies ведет себя на машине без установленного отладчика, будет ли он вызывать тот же код?

обновить некоторые пояснения по коду: собственный C ++ вызывает делегат CLI (для которого получен указатель на встроенную функцию с помощью GetFunctionPointerForDelegate , который, в свою очередь, вызывает C # System.Action. Это действие обновляет строка (привязанная к метке WPF) и вызывает событие propertychanged. Это каким-то образом вызывает переполнение буфера (при очень быстром обновлении) в безымянном потоке, который не был создан непосредственно в моем коде.

update изучает ] SetUnhandledExceptionFilter , который сначала ничего не делал, я нашел эту отличную статью , объясняющую, как перехватить любое исключение. Она работает, и я смог написать минидамп в фильтре исключений, установленном дамп дает в основном ту же информацию, что и подключение отладчика: реальная проблема, похоже, в том, что строка состояния перезаписывается (вызывается из собственного потока), в то же время читается из потока пользовательского интерфейса. Все хорошо такое, но это требует подключения dll, что не является моим любимым методом решения проблем. Другой способ все равно был бы хорош.

5
задан stijn 10 January 2012 в 19:26
поделиться