WIndows 上的 DLL 中未使用 Breakpad 异常处理程序?
Breakpad exception handler not used in a DLL on WIndows?
我正在开发一个加载 C++ DLL 的 python 应用程序。在这样的 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;
};
P.S。 : Breakpad 处理程序在我们的 linux 版本的应用程序中工作正常,它具有相同的设置。
感谢您的帮助。
崩溃及其原因在 Windows 和 Linux 上的处理方式完全不同。让我们从 Linux 案例开始,并解释为什么该案例能够成功运行。
在 Linux 上,崩溃处理是通过信号处理程序在您的程序端完成的。这些是为您的进程在系统中注册的,一旦这样的信号被发送到您的进程就会被调用。信号处理程序完全独立于您的正常代码流运行,并且无论信号在您的程序中出现在哪里,都会调用相同的信号处理程序。
Breakpad 为 SIGSEGV、SIGILL 等典型信号安装信号处理程序...
在 Windows 上,崩溃和相关问题的处理不使用信号,而是使用一种称为 SEH (structured exception handling) 的特殊异常。这些异常的工作方式与普通 C++ 异常非常相似,但通常是通过 __except 而不是 catch 捕获。这种正常的异常处理要求您的 google_breakpad::ExceptionHandler
对象被识别崩溃的处理程序的自动清理破坏。 Windows 上的 Linux 信号处理程序没有等效的解决方案。
在一个典型的应用程序中,如果你想通过 breakpad 报告崩溃,你通常会在启动代码的早期创建 google_breakpad::ExceptionHandler 对象,这样它会在 SEH 未捕获异常时被破坏
到达那个地方。
我正在开发一个加载 C++ DLL 的 python 应用程序。在这样的 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;
};
P.S。 : Breakpad 处理程序在我们的 linux 版本的应用程序中工作正常,它具有相同的设置。
感谢您的帮助。
崩溃及其原因在 Windows 和 Linux 上的处理方式完全不同。让我们从 Linux 案例开始,并解释为什么该案例能够成功运行。
在 Linux 上,崩溃处理是通过信号处理程序在您的程序端完成的。这些是为您的进程在系统中注册的,一旦这样的信号被发送到您的进程就会被调用。信号处理程序完全独立于您的正常代码流运行,并且无论信号在您的程序中出现在哪里,都会调用相同的信号处理程序。 Breakpad 为 SIGSEGV、SIGILL 等典型信号安装信号处理程序...
在 Windows 上,崩溃和相关问题的处理不使用信号,而是使用一种称为 SEH (structured exception handling) 的特殊异常。这些异常的工作方式与普通 C++ 异常非常相似,但通常是通过 __except 而不是 catch 捕获。这种正常的异常处理要求您的 google_breakpad::ExceptionHandler
对象被识别崩溃的处理程序的自动清理破坏。 Windows 上的 Linux 信号处理程序没有等效的解决方案。
在一个典型的应用程序中,如果你想通过 breakpad 报告崩溃,你通常会在启动代码的早期创建 google_breakpad::ExceptionHandler 对象,这样它会在 SEH 未捕获异常时被破坏
到达那个地方。