【问题标题】:terminate called after throwing an instance of 'Poco::SystemException'在抛出“Poco::SystemException”实例后调用终止
【发布时间】:2009-11-19 11:01:58
【问题描述】:

有时(大约 100 次运行中的 1 次),我的程序会以以下消息终止:

terminate called after throwing an instance of 'Poco::SystemException'
  what():  System exception

我的代码不是捕获异常的代码(我所有的捕获都更冗长),我不确定它是在哪里捕获的。 异常很可能确实包含有用的消息,但它不是通过 what() 方法而是通过 displayText() 方法返回的。

字符串“在抛出一个实例后调用终止”在 Google 中大约有 600k,因此它可能是由编译器或某个公共库(pthread?)插入的代码打印出来的。 我只在程序在 Linux 上运行时看到此错误消息(从不在 Windows 上)。

有人知道这个未捕获的异常是在什么代码中捕获的吗?

【问题讨论】:

  • 是的,一个库会生成该消息,虽然那不是 pthread 库,但它是编译器附带的 C++ 库。

标签: c++ exception-handling


【解决方案1】:

有人知道这个未捕获的异常是在什么代码中捕获的吗?

根据定义,未捕获的异常在任何地方都没有捕获。

如果无法处理异常,C++ 异常机制将调用std::terminate()(请参阅包含标头<exception>),这将调用可自定义的终止处理程序。在您的平台上,标准终止处理程序会打印 std::exception::what() 的输出(Poco 的异常继承自)。不幸的是,Poco 异常的设计方式,它不会包含任何有用的信息。

有多种方式无法处理异常:

  • 找不到合适的catch() 处理程序,展开机制退出main()。您可以尝试将main() 代码包装在try...catch 中以打印异常的displayText()
  • 函数退出时出现与其异常规范 (... functionname(...) throw(...)) 不匹配的异常。这将调用std::unexpected(),而后者又将调用std::terminate()(默认情况下)。
  • 在另一个异常的展开过程中调用的析构函数中引发异常。永远不要在析构函数中抛出异常!
  • 尝试创建原始异常对象时引发异常。永远不要在自定义异常类中抛出异常!

当使用 Poco 线程并且线程被未处理的异常终止时,Poco 将调用其内部的ErrorHandler 并且程序不会退出,所以我怀疑这是一个线程问题。

【讨论】:

  • 谢谢。为了更容易调试,我破解了 Poco 中的 Exception::what() 以将 displayText() 打印到标准输出。这使得查看未捕获异常的实际消息成为可能。我仍在努力找出实际原因,异常是关于无法锁定互斥锁,并且可能是从某个析构函数中以某种方式抛出的。
  • 原来这个 bug 是在 Poco ErrorHandler 中,或者至少是一个 bug。看看这个:pocoproject.org/forum/…
【解决方案2】:

我遇到了同样的错误。我在 Poco::Runnable 类的 run 函数中使用了 try catch 块。我从这个类中删除了 try catch 块,并使用 Poco::ErrorHandler 类的派生类来处理错误。在此之后,我停止收到此错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2018-01-06
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多