Search code examples
multithreadingc++11exceptiondynamicthrow

C++11: Clang on Mac doesn't catch exception thrown by std::thread function?


I've got a very simple program as:

#include <iostream>
#include <string>
#include <thread>
using namespace std;
struct N{
    string s;
    N(){}
    ~N(){cout<<"N dtor"<<endl;}
};

void f(){
    N n;
    throw 0;
}
int main(){
    try{
        thread a(f), b(f);
        a.join();
        b.join();
    }catch(exception& e){
        cout<<e.what()<<endl;
    }
    return 0;
}

On my mac+clang environment, the running result is:

libc++abi.dylib: terminating with uncaught exception of type int
Abort trap: 6

It doesn't print the "N dtor" as I expected. So my question, if std::thread function throws an exception, how to catch/deal with it? There's no guarantee that the code inside a thread function doesn't throw any exception.

I tried it on linux, and the exception could be caught and print:

Enable multithreading to use std::thread: Operation not permitted

Thanks a lot.


Solution

  • If an exception is thrown in a thread, it must be caught in the same thread (or not at all). In your example, the try block can catch exceptions specifically from the attempts to create or join the threads, but not exceptions caused by code running in the threads.

    And if you think about it, this is how it has to be. Your example tries to ensure that you don't leave the try block until the threads have completed, but that's not something that can generally be guaranteed. Even in your example, if the join calls tried to throw exceptions that originated in the target thread (they don't, but for the sake of argument...), you'd never reach the join(b) call and nothing would guarantee that you're still in the try block when b's thread throws its exception.

    The flow control for one thread to catch another's exception simply doesn't work. If you need this kind of functionality, you could put an exception handler in the worker thread and have it communicate exception state back to the master thread using established inter-thread communication mechanisms.