Обработчик исключений Breakpad не используется в DLL на WIndows?


Я работаю над приложением python, которое загружает библиотеку DLL C++. В такой DLL мы делаем всю тяжелую работу,и мы хотим добавить в нее систему отчетов о сбоях Google breakpad. В Windows мы создаем экземпляр обработчика исключений после загрузки этой библиотеки DLL. Однако этот обработчик исключений никогда не вызывается при возникновении сбоя и мини-дамп никогда не записывается. Когда мы используем ту же настройку для простого консольного приложения C++, все работает нормально. Очевидно, что-то мешает обработчику исключений быть будет сообщено только тогда, когда это instanciated в библиотеке DLL.

Как мы можем убедиться,что обработчик исключений Google breakpad вызывается в DLL?

Ниже приведена используемая нами настройка. Фреймворк-это синглтон, который создается непосредственно перед тем, как мы начнем использовать 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;
};

P.S. : обработчик Breakpad прекрасно работает в нашей linux-версии приложения, которая имеет ту же настройку.

Спасибо за помощь.

1 2

1 ответ:

Сбои и их причины обрабатываются совершенно по-разному в Windows и Linux. Давайте начнем с случая Linux и объясним, почему этот случай успешно работает.

В Linux обработка сбоев выполняется на стороне вашей программы через обработчик сигналов. Они регистрируются для вашего процесса в системе и вызываются, как только такой сигнал был отправлен в ваш процесс. Обработчик сигнала работает полностью независимо от вашего обычного потока кода, и тот же обработчик сигнала будет вызывается везде, где сигнал берет начало в вашей программе. Breakpad устанавливает обработчики сигналов для типичных сигналов, таких как SIGSEGV, SIGILL,...

В Windows обработка сбоев и связанных с ними проблем не использует сигналы, а вместо этого использует особый вид исключений, называемый SEH (structured exception handling ). Эти исключения работают очень похоже на обычные исключения C++, но обычно перехватываются Через _ _ за исключением вместо catch. Этот нормальный вид обработки исключений требует что ваш объект google_breakpad::ExceptionHandler уничтожается автоматической очисткой для обработчика, распознающего сбой. В Windows нет эквивалентного решения для обработчика сигналов Linux. В типичном приложении, если вы хотите сообщить о сбоях через breakpad, вы обычно создаете объект google_breakpad:: ExceptionHandler довольно рано в коде запуска, так что он будет уничтожен, когда SEH uncaught исключение достигает этого места.