C ++ exception in worker thread

An unused exception behaves differently for the main thread and another std :: thread.

here is the test program

#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(); } } 

above code (C ++ 11) compiled by GCC 5.4 to work without arguments

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

run 1 arg:

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

So, stack unwinding is done in the worker thread, but not in the main thread, WHY?

I ask because I would like the kernel to provide useful information about the reverse stack in both cases (for an uncaught exception).

Thanks in advance!


Further research shows that the noexcept keyword adds the noexcept keyword to the body of the stream function. mytest () can partially solve my problem because unwinding will fail, but this is not a good solution, because recovery will be partially partial if mytest () calls another function without any guarantees and actually throws an uncaught exception.


Update: thanks to all comment providers, now I understand that the C ++ exception does not support feedback, and GCC, as a C ++ implementation, has the right to choose not to untie when the excluded exception is selected from the main thread and unwinds when from the workflow.


Update: Special thanks to Sid S and Jive Dadson, I have to confuse some concepts: 1) exception / error handling; 2) assertion of the runtime 3) Segment error, 2 and 3 are similar, they are UN recovery errors, interruption is immediately the only choice, they are also debugger friendly because the package is not involved. they should not be implemented using the concept of exceptions in general. the exception is always supposed to be caught, although the exception of the excluded exception from main () is not recommended.

+5
source share
2 answers

You must catch the exception in the thread where this occurs. The default handler will call terminate() wherever it is, unwind or not, depending on the implementation.

+1
source

Why? It is as it is. Starting with C ++ 11, there is some support for handling exceptions thrown in threads other than the main one, but you will need to bind threads to exceptions and re-throw them. Here is how.

 #include <thread> #include <iostream> 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[]) { std::exception_ptr exception_ptr = nullptr; if (argc == 1) { mytest(0); } else { std::thread th([&exception_ptr]() { try { mytest(0); } catch (...) { exception_ptr = std::current_exception(); } }); th.join(); if (exception_ptr) { try { std::rethrow_exception(exception_ptr); } catch (const std::exception &ex) { std::cerr << "Thread exited with exception: " << ex.what() << "\n"; } } } } 
+1
source

Source: https://habr.com/ru/post/1275066/


All Articles