我有一个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;
}
答案 0 :(得分:16)
您可以使用gdb或其他调试器执行此操作。告诉调试器在抛出任何异常时停止(在gdb中,命令是热闹的catch throw
)。然后,您不仅会看到异常的类型,还会看到它的确切位置。
另一个想法是注释掉catch (...)
并让你的运行时终止你的应用程序,并希望告诉你更多关于异常的信息。
一旦你弄清楚异常是什么,你应该尝试用从std::exception
派生的东西替换或扩充它。完全不得不catch (...)
。
如果您使用GCC或Clang,您还可以尝试__cxa_current_exception_type()->name()
获取当前例外类型的名称。
答案 1 :(得分:5)
作为John Zwinck关于注释掉catch(...)
块以让运行时终止应用程序并希望提供更多信息的建议的变体,你可以
catch (...)
{
log("Unknown exception caught in [sensible info here]; will rethrow it");
throw;
}
然后你至少会知道你的程序在哪里发生错误(如果有多种可能性)。
答案 2 :(得分:2)
至少在Windows上,一种可能性是使用MiniDumpWriteDump编写一个minidump来获取异常以及堆栈跟踪,内存和大量有用的调试信息。
答案 3 :(得分:2)
您可以使用调试器并启用break on throw,假设您的异常非常特殊,这是了解其来源的好方法。
如果您在Windows上使用catch(...),还应该发出警告。在某些构建选项下,这将捕获SEH异常,这些是您不应该尝试处理的事情,例如读取或写入超出范围的内存。
答案 4 :(得分:2)
代码(即不使用调试器)从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
}
}
这种方法的捕获(可以这么说)是它需要程序员知道异常可能是什么(例如,来自第三方库的文档)。 |