Преобразовать std::exception в EXCEPTION_POINTERS
У меня может быть полное недопонимание, как использовать API Google Breakpad, и я открыт для комментариев / предложений / грубых замечаний, если это так. Я пытаюсь вызвать следующую функцию C++:
bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
У меня есть ссылка на std::exception
:
try {
return QApplication::notify(receiver, event);
} catch (std::exception &ex) {
eh_.WriteMinidumpForException(?????);
// ... do some more stuff and ultimately kill this process
}
(eh_
это google_breakpad::ExceptionHandler
.)
Что я положил в ?????
Предыстория: Причина, по которой это необходимо (я думаю), заключается в том, что Qt не будет поддерживать исключение, генерируемое в обработчике событий. Он не будет распространяться правильно, и, следовательно, созданный Breakpad мини-дамп совершенно бесполезен, потому что фактический контекст исключения был потерян. Вместо этого вы должны перехватить все исключения и обработать их в переопределении QApplication::notify()
Это то, что я пытаюсь сделать. В случае исключения я хочу немедленно написать свой мини-дамп для этого исключения (что звучит как WriteMinidumpForException
будет делать), а затем уведомить пользователя и выйти из приложения. Но я не уверен, что передать как EXCEPTION_POINTERS*
параметр.
2 ответа
В компиляторе MSVC исключения C++ добавляются в собственную систему исключений Windows (SEH, Структурная обработка исключений). Однако существует довольно большое несоответствие импеданса, концепция фильтра исключений не очень подходит для C++. К тому времени, когда обработчик перехвата ловит исключение, исключение SEH уже обработано, и стек разматывается. Информация EXCEPTION_POINTERS -gonzo. Фильтры исключений действительно существуют, именно так они фильтруют определенный тип, который вы хотите перехватить, однако они автоматически генерируются компилятором. Нет разумного синтаксиса C++, чтобы сделать их полезными.
Вам нужно углубиться в поддержку компилятора для обработки исключений SEH. Использовать __try, __except
ключевые слова (__finally
необязательно), и ваш фильтр перехватывает код исключения для исключения C++, 0xe04d5343 ('MSC'). Однако вы теряете возможность отлавливать определенный тип исключений C++, так как сантехника скрыта в CRT без источника. Поместите C++ попробуйте внутри __try
чтобы исправить это так, ваш __except
видит только исключения, которые код C++ не фильтровал.
Использование SetUnhandledExceptionFilter() является еще одним способом сделать это, кстати, вы действительно должны рассматривать его как конечную поддержку любого необработанного исключения, независимо от расположения кода. Это лучший способ создать мини-дамп аварийного приложения. И последнее, но не менее важное: создание мини-дампа аварийного приложения внутри самого процесса - не лучший подход. Есть много шансов, что это не будет работать хорошо, состояние процесса может быть сильно повреждено. Один из режимов сбоя - блокировка кучи процесса. Не исключено, что повреждение кучи является очень распространенной причиной аварии. Исправьте это с помощью "процесса защиты", используйте именованное событие, чтобы подать сигнал на создание минидампа. Вашему фильтру исключений нужно только установить событие, которое всегда работает.
Исключения в Windows SEH и C++ никоим образом не переплетаются - простой способ решить эту проблему - использовать собственную __try __except, например, разыменование нулевого указателя.
Что-то вроде:
__try {
* (int *) 0 = 0;
}
__except
(
eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
)
{
}