从 catch(...) 捕获的异常中获取一些信息?

Get some information from exception caught with catch(...)?

我有一个 try catch 子句,其中最外面的 catch(...) 直到现在才发生。经过一些更改后,在某个地方抛出了我不处理其他情况的异常。即使我用 (...)?

捕获异常,有没有办法至少获取一些有关异常的信息?
catch (const cone::BeginnersLibException& ex) 
{
    // handle the exception
}
catch (const std::exception& ex) 
{
    // handle std exception
} 
catch (...) 
{
    log("Unknown exception caught.");
    // How can I get more information about this exception?
}

编辑:这里是适合我的代码片段:

#include <cxxabi.h>

// more code here 
} catch (...) {
    std::string exName(abi::__cxa_current_exception_type()->name());
    std::cout<<"unknown exception: "<< exName <<std::endl;
    throw;
}

您可以使用 gdb 或其他调试器执行此操作。告诉调试器在抛出任何异常时停止(在 gdb 中,命令很有趣 catch throw)。然后您不仅会看到异常的类型,还会看到异常的确切来源。

另一个想法是注释掉 catch (...) 并让您的运行时终止您的应用程序,并希望告诉您更多有关异常的信息。

一旦你弄清楚异常是什么,你应该尝试用确实从 std::exception 派生的东西替换或扩充它。必须 catch (...) 一点都不好。

如果您使用 GCC 或 Clang,您也可以尝试 __cxa_current_exception_type()->name() 获取当前异常类型的名称。

作为 John Zwinck 关于注释掉 catch(...) 块以使 运行 时间终止应用程序并希望提供更多信息的建议的变体,您可以

catch (...) 
{
  log("Unknown exception caught in [sensible info here]; will rethrow it");
  throw;
}

那么你至少会知道错误发生在你的程序中的什么地方(如果有多种可能性的话)。

至少在 Windows 上,还有一种可能性是使用 MiniDumpWriteDump 编写小型转储以获取异常以及堆栈跟踪、内存和许多有用的调试信息。

您可以使用调试器并启用抛出时中断,假设您的异常确实异常,这是了解其来源的好方法。

还有一个警告,如果你在 windows 上使用 catch(...)。在某些构建选项下,这将捕获 SEH 异常,这些是您永远不应该尝试处理的事情,例如越界读取或写入内存。

代码中(即不使用调试器)从 catch(...) 块中的异常中获取信息的唯一方法是重新抛出异常,并用特定的子句捕获它。

例如

try
{
    // code that might throw something
}
catch (...)
{
    try_to_interpret_exception();
}

void try_to_interpret_exception()   // we assume an exception is active
{
    try
    {
         throw;    // rethrow the exception.  Calls terminate() if no exception active
    }
    catch (std::exception &)
    {
         // handle all exception types derived from std::exception
         //    this covers all exceptions that might be thrown by
         //    the standard C++ library
    }
    catch (specific_exception &e1)
    {
        //  handle all exception types derived from specific_exception
    }
    catch (another_specific_exception &e2)
    {
         // etc
    }
}

这种方法的问题(可以这么说)是它要求程序员对异常可能是什么有一些了解(例如来自第三方库的文档)。 |