Преобразовать std :: exception в EXCEPTION_POINTERS - PullRequest
4 голосов
/ 15 марта 2011

Я могу быть полностью , неправильно понимая, как использовать 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 ]

7 голосов
/ 15 марта 2011

В компиляторе MSVC исключения C ++ добавляются в собственную систему обработки исключений Windows (SEH, Структурная обработка исключений).Однако существует довольно большое несоответствие импеданса, концепция фильтра исключений не имеет хорошего соответствия в C ++.К тому времени, когда обработчик catch перехватывает исключение, исключение SEH уже обработано, и стек разматывается.Информация EXCEPTION_POINTERS - gonzo.Фильтры исключений действительно существуют, именно так они фильтруют определенный тип, который вы хотите перехватить, однако они автоматически генерируются компилятором.Не существует разумного синтаксиса C ++, чтобы сделать их полезными.

Вам нужно углубиться в поддержку компилятора для обработки исключений SEH.Используйте ключевые слова __try, __except (__finally необязательно) и ваш фильтр перехватывает код исключения для исключения C ++, 0xe04d5343 ('MSC').Однако вы теряете возможность отлавливать определенный тип исключений C ++, так как сантехника похоронена в CRT без источника.Поместите C ++ try в __try, чтобы исправить это, чтобы ваш __except видел только те исключения, которые код C ++ не фильтровал.

Использование SetUnhandledExceptionFilter () - это еще один способ сделатьэто кстати, вы действительно должны рассматривать это как окончательную защиту любого необработанного исключения, независимо от расположения кода.Это лучший способ создать мини-дамп аварийного приложения.И последнее, но не менее важное: создание мини-дампа аварийного приложения внутри самого процесса - не лучший подход.Есть много шансов, что это не сработает, состояние процесса может быть сильно повреждено.Один из режимов сбоя - блокировка кучи процесса.Не исключено, что повреждение кучи является очень распространенной причиной аварий.Исправьте это с помощью «процесса защиты», используйте именованное событие, чтобы подать сигнал на создание минидампа.Фильтру исключений нужно только установить событие, которое всегда работает.

3 голосов
/ 15 марта 2011

Исключения Windows SEH и c ++ никоим образом не переплетаются - простой способ решить эту проблему - использовать собственную __try __except, например, разыменование нулевого указателя.

Что-то вроде:

__try {
  * (int *) 0 = 0;
} 
__except 
    (
        eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
    ) 
{
}
...