0

I am creating a few std::threads that will be detached. I would like to have these running for a long time and would like these to handle exceptions themselves.

I create a thread using std::thread(Function) and have called detach before releasing the mutex and where Function does following:

void BlockStart() noexcept {
    std::lock_guard<std::mutex> sync(lock);
}
void Function()
{
   BlockStart();
    try 
    {
        throw;
     }
     catch(...)
     {
         std::cerr << "Caught something...\n";
     }
} 

Everytime I run this code, the exception handler is not called. The default handler of std::terminate() is called which calls abort.

How do I get an std::thread started thread to handle exceptions?

2 Answers2

3

Based on the answer of this question: https://stackoverflow.com/a/5378736/1619294

If you do a throw; on its own, and there isn't a current exception for it to rethrow, then the program ends abruptly. (More specifically, terminate() is called.)

You may want to do something like

void Function()
{
    try 
    {
        SomeOtherFunction();
    }
    catch(...)
    {
        std::cerr << "Caught something...\n";
    }
}

Also, note that the lock guard + mutex inside the BlockStart() function will only block within the function's duration, and will not persist after it returns. The solution would be to have the lock guard lock inside Function()

void Function() {
    std::lock_guard<std::mutex> sync(lock);
    ...
Community
  • 1
  • 1
Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
1

Calling throw by itself re-throws the current exception, but that only works when called inside of a catch block. If you try to call throw by itself inside of a try block when there is no current exception, terminate() is called and your app dies. You must tell throw WHAT to throw when inside of a try block, eg:

void Function()
{
    BlockStart();
    try 
    {
        throw std::runtime_error("something bad happened");
    }
    catch(const std::exception& e)
    {
        std::cerr << "Caught something... " << e.what() << std::endl;
    }
} 

Also, using std::lock_guard inside of BlockStart() is useless. sync is a local variable, so it will go out of scope and release the mutex when BlockStart() exits. It only makes sense to use it if it actually does something while the mutex is locked, eg:

void BlockStart() noexcept
{
    std::lock_guard<std::mutex> sync(lock);
    // do something here while the mutex is locked...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770