如何捕获DLL中的错误

时间:2011-04-08 15:04:42

标签: c++ dll exception-handling

我们有一个.NET程序,可以调用非托管C ++中的主要功能。我在.NET端有一个全局异常捕获程序来捕获任何未处理的错误,但是非托管C ++ DLL中的访问冲突等错误可以在不进行任何记录的情况下关闭程序。在DLL中添加“全局”异常捕获器的最佳方法是什么?我可以在DllMain中这样做吗?

2 个答案:

答案 0 :(得分:1)

您可以使用/EHa异常处理标志,这将导致您的C ++ catch (...)也捕获结构化异常,即访问冲突。这样做的缺点是你无法看到异常是什么。

或者,您可以使用结构化异常处理程序__try { } __except(FILTER) { }来处理结构化异常。这允许您输出捕获的异常类型。但是,在具有__try的函数中可以执行的操作存在限制,例如没有C ++异常处理或具有析构函数的对象。

但是,您可以通过调用包含C ++异常处理和原始代码的函数来绕过__try限制。

void main() {
  __try {
    Foo();
  }
  __except(EXCEPTION_EXECUTE_HANDLER) {
    // Log some error regarding the structured exception
  }
  return 0;
}

void Foo() {
  try {
    SomeCPPObject bar(1,2);
    DoSomeStuff();
  }
  catch (const std::exception&) {
    // Log the C++ exception
  }
}

但要小心,因为在引发结构化异常后通常不应继续执行,因为程序的状态可能会被完全破坏。最好只使用这种类型的异常处理在退出之前记录错误。

答案 1 :(得分:1)

CLR无法捕获由本机代码启动的线程中引发的任何硬件异常。唯一的方法是使用SetUnhandledExceptionFilter(),您注册的回调在Windows即将拆除进程之前由Windows调用。

在一个也有托管代码的程序中使用它会充满陷阱和陷阱。 CLR也使用它,它必须生成NullReferenceException和DivideByZeroException等异常。你必须非常小心,不要破坏它。做一些事情,比如调用GetThreadId()并且只过滤你知道的本机线程的异常非常重要。接下来你要做的就是使用MiniDumpWriteDump()生成一个minidump,以便你可以调试崩溃。