11

In which thread is called the terminate handler:

  1. when an exception is thrown inside a noexcept function?

  2. when the user call std::terminate()?

  3. at start up or destruction of thread?

Is it defined in the standard, will I have access to thread_local objects?

Oliv
  • 17,610
  • 1
  • 29
  • 72
  • 1
    My common sense tells me it will be called on the thread which called `std::terminate`? I do believe the Standard doesn't address this explicitly. – DeiDei May 31 '17 at 16:17
  • I believe it is unspecified behavior (or might be undefined?) – Paul Stelian May 31 '17 at 16:18
  • I'd say on the thread that actually set up the handler, though idk – Paul Stelian May 31 '17 at 16:18
  • 2
    I can't imagine there being some mechanism to interrupt whatever some other thread might be doing to get it to run `std::terminate`. I would think the thread calling `std::terminate` gets to run it. – Galik May 31 '17 at 16:22
  • 3
    Making code run on a specific other thread is highly untrivial. So it just doesn't, it runs on whatever thread suffered the heart-attack. Easy to try for yourself, makes you feel better about it. – Hans Passant May 31 '17 at 16:27
  • Thanks, you have conviced me. – Oliv May 31 '17 at 16:30
  • 1
    I just checked in the online compiler, the threads that terminates is the one that calls std::terminate. – Rinat Veliakhmedov May 31 '17 at 16:32

1 Answers1

3

This answer sum up answers given in comments and an answer now deleted:

  • It is not specified in the standard (DeiDei, I have checked too in N4618)

  • Nevertheless, for technical reasons it is unlikely that the handler is called in an other thread that the one who caused the call to std::terminate (Galik,Hans Passant)

  • it has been verified on online compiler (Rinat Veliakhmedov), the terminate handler is called in the thread that causes terminate to be called.

You can test it yourself with this code from a deleted answer:

#include <string>
#include <exception>
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mutex;
const auto& id = std::this_thread::get_id;
const auto print = [](std::string t){
    std::lock_guard<std::mutex> lock(mutex);
    std::cout << id() << " " << t << std::endl;
};

void my_terminate_handler(){
    print("terminate");
    std::abort();
}

void throwNoThrow() noexcept { throw std::exception(); }
void terminator()            { std::terminate();       }

int main() {
    std::set_terminate(my_terminate_handler);
    print("main");    
#ifdef  CASE1
    auto x1 = std::thread(throwNoThrow);
#elif CASE2
    auto x1 = std::thread(terminator);
#elif CASE3    
    auto x1 = std::thread(throwNoThrow);
#endif
    x1.join();
}

Conclusion It is unspecified but it seems that the handler is always be called in the thread that causes std::terminate to be called. (tested on gcc-5.4, gcc-7.1, clang-3.8 with pthreads)

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Oliv
  • 17,610
  • 1
  • 29
  • 72