从 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
}
}
这种方法的问题(可以这么说)是它要求程序员对异常可能是什么有一些了解(例如来自第三方库的文档)。
|
我有一个 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
}
}
这种方法的问题(可以这么说)是它要求程序员对异常可能是什么有一些了解(例如来自第三方库的文档)。 |