工作线程中的C++未捕获异常

Tin*_* LI 5 c++ multithreading stack-unwinding uncaught-exception

未捕获的异常对主线程和另一个std :: thread的行为有所不同.

这是测试程序

#include <thread>

class XXX{
public:
  XXX(){std::fprintf(stderr, "XXX ctor\n");}
  ~XXX(){std::fprintf(stderr, "XXX dtor\n");}
};

void mytest(int i)
{
    XXX xtemp;
    throw std::runtime_error("Hello, world!");
}
int main(int argc, char *argv[])
{
    if(argc == 1) {
        mytest(0);
    }else{
        std::thread th([&]{mytest(0);});
        th.join();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码(C++ 11),由GCC 5.4编译运行,没有args

XXX ctor
terminate called after throwing an instance of 'std::runtime_error'
   what():  Hello, world!
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

运行1 arg:

XXX ctor
XXX dtor
terminate called after throwing an instance of 'std::runtime_error'
  what():  Hello, world!
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

因此,堆栈展开是在工作线程中执行的,而不是在主线程中执行,为什么?

我问,因为我希望核心转储在两种情况下都提供有用的堆栈回溯信息(对于未捕获的异常).

提前致谢!!!


进一步的试验表明,向线程函数体添加noexcept关键字mytest()可以部分解决我的问题,因为展开会失败,但它不是一个好的解决方案,因为如果mytest()调用另一个没有noexcept保证且实际抛出的函数,unwind仍然会部分发生未被捕获的例外.


更新:感谢所有评论提供者,现在我理解C++异常不是回溯友好的,GCC作为C++实现,可以自由选择不从主线程抛出未捕获异常时解除,并从工作线程解除.


更新:特别感谢Sid S&Jive Dadson,我必须混淆一些概念:1)异常/错误处理; 2)运行时断言3)段故障,2和3类似,它们是UN可恢复的错误,立即中止是唯一的选择,它们在调试器中也是回溯友好的,因为不涉及堆栈展开.它们不应该使用异常概念来实现.异常应该始终被捕获,让未被捕获的异常离开main()不是推荐的用法.

Sid*_*d S 2

您应该在发生异常的线程中捕获该异常。默认处理程序将terminate()在任何位置调用,是否展开取决于实现。