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

时间:2015-02-16 09:27:06

标签: c++ exception-handling

我有一个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;
}

5 个答案:

答案 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
    }
}

这种方法的捕获(可以这么说)是它需要程序员知道异常可能是什么(例如,来自第三方库的文档)。 |