【问题标题】:why does pthread_exit throw something caught by ellipsis?为什么 pthread_exit 会抛出被省略号捕获的东西?
【发布时间】:2012-07-12 05:53:12
【问题描述】:

如果pthread_create调用的函数具有以下结构

try{
  ...code....
  pthread_detach(pthread_self());
  pthread_exit(NULL);
}catch(...){
  std::cout<<"I am here"<<std::endl;
}

为什么在执行pthread_exit 时会调用省略号的异常处理程序? (注意std::exception,例如,不会被抛出)

【问题讨论】:

  • 你在哪个编译器下看到这个?
  • @Fabio 也许堆栈上某个对象的一些析构函数正在抛出。
  • @DaveS g++ TorstenRobitzki 谢谢你,我虽然也一样,但情况是由eran解释的

标签: c++ exception exception-handling pthreads cancellation


【解决方案1】:

至少在 GCC 中 pthread_exit 可能会抛出 ___forced_unwind 异常,用于在线程退出期间展开堆栈。它不是从std::exception 继承的,因此不能被视为一个。如果您确实捕获了该异常,请务必重新throw 它以便它可以完成它的工作:

try {
...
} catch (abi::___forced_unwind&) {
    throw;
} catch (...) {
    // whatever
}

抛出异常的原因是pthread_exit 被指定为永不返回。让它抛出保证了堆栈分配的变量的清理,并且在它的位置之后不会执行代码(除非你捕捉到展开异常......)。然而,这不是可移植的,例如 Clang 使用了完全不同的机制。

顺便说一句,这是catch (...) 成语弊大于利的又一个例子。它有时用于“稳定”抛出未知异常的代码。但这只会将损害的可见性推迟到以后的时间和地点,从而无法确定问题的真正根源。在这种捕获中唯一合理的做法是最少的清理,可能是记录,然后重新抛出。由于未处理的异常而崩溃的进程并不是一个漂亮的景象,但它可以提供一个可调试的崩溃转储,清楚地显示错误的命令。但这只是我对catch (...)的怨恨,与pthread_exit几乎没有关系……

【讨论】:

  • 非常感谢,原来如此!我猜你的 throw 是为了防止 FATAL: exception not rethrow 谢谢!
  • @Fabio:abi::__forced_unwind exception 也可以在已用pthread_cancel 取消的线程中抛出。终止 pthread 时要小心省略号。
  • 非常有趣,但我有兴趣在 __force_unwind 上了解更多信息,并且 2012 链接已损坏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 2019-08-03
  • 2019-03-26
  • 1970-01-01
相关资源
最近更新 更多