Я работаю над приложением Python, которое загружает C ++ DLL. В такой DLL мы делаем всю тяжелую работу и хотим добавить в нее систему отчетов о сбоях Google Breakpad. В Windows мы создаем обработчик исключений после загрузки DLL. Однако этот обработчик исключений никогда не вызывается, когда происходит сбой, и мини-дамп никогда не записывается. Когда мы используем ту же настройку для простого консольного приложения C ++, все работает отлично. Очевидно, что-то препятствует уведомлению обработчика исключений только тогда, когда он создается в DLL.
Как мы можем убедиться, что обработчик исключений Google Breakpad вызывается в DLL?
Ниже приведены настройки, которые мы используем. Framework — это синглтон, который создается непосредственно перед тем, как мы начнем использовать DLL.
# include <client/windows/handler/exception_handler.h>
bool callback(
const wchar_t* /*dump_path*/, const wchar_t* /*minidump_id*/,
void* /*context*/, EXCEPTION_POINTERS* /*exinfo*/, MDRawAssertionInfo* /*assertion*/,
bool succeeded )
{
std::cout << "dump callback called" << std::endl;
return succeeded;
}
class Framework
{
Framework()
: handler{ std::make_unique<google_breakpad::ExceptionHandler>(
L".", // dump path
nullptr, // no filter
callback, // to call after writing the minidump
nullptr, // callback does not use context
google_breakpad::ExceptionHandler::HANDLER_ALL ) }
{
std::cout << "Exception handler registered" << std::endl;
}
~Framework()
{
std::cout << "Exception handler destroyed" << std::endl;
}
private:
std::unique_ptr<google_breakpad::ExceptionHandler> handler;
};
Постскриптум : Обработчик Breakpad отлично работает в нашей версии Linux, которая имеет те же настройки.
Спасибо за вашу помощь.
Сбои и их причины обрабатываются совершенно по-разному в Windows и в Linux. Давайте начнем со случая Linux и объясним, почему этот случай работает успешно.
В Linux обработка сбоев выполняется на стороне вашей программы через обработчик сигналов. Они регистрируются для вашего процесса в системе и вызываются после отправки такого сигнала вашему процессу. Обработчик сигнала работает полностью независимо от вашего обычного кодового потока, и тот же обработчик сигнала будет вызываться везде, где сигнал возникает в вашей программе.
Breakpad устанавливает обработчики сигналов для типичных сигналов, таких как SIGSEGV, SIGILL, …
В Windows обработка сбоев и связанных с ними проблем не использует сигналы, а использует особый вид исключений, называемый SEH (обработка структурированных исключений). Эти исключения работают очень похоже на обычные исключения C ++, но обычно перехватываются через __except вместо catch. Этот нормальный вид обработки исключений требует, чтобы ваш google_breakpad::ExceptionHandler
объект уничтожается автоматической очисткой для обработчика, распознающего сбой. В Windows нет эквивалентного решения для обработчика сигналов Linux.
В типичном приложении, если вы хотите сообщить о сбоях через панель разбивки, вы обычно создаете объект google_breakpad :: ExceptionHandler довольно рано в коде запуска, так что он будет уничтожен, когда SEH не найдет исключение
достигает этого места.
Других решений пока нет …