11

As stated in http://en.cppreference.com/w/cpp/error/terminate there are many reasons to call terminate. I can imagine case where just almost in the same time some of these reasons happen in two threads.

Q1 Can the terminate function set by std::set_terminate be called twice or more at the same time, by the same time I mean second call begins before first has ended.

  Thread1   Thread2
    |          |
    _          |
    t          |
    e          |
    r          |
    m          |
    i          _
    n          t
    a          e
    t          r
    e          m
    -          ?

Q2 If Q1==YES, then what happens if first terminate ended. I guess if it ended with std::abort, then program ends, but what happens if user provided terminate does not abort program?

Q3 Is the terminate function set by std::set_terminate called in context of the thread which caused this terminate call?

Nemo
  • 70,042
  • 10
  • 116
  • 153
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112

1 Answers1

7

Q1

Yes, std::terminate can be called concurrently.

Q2

The standard says it is undefined behavior for a terminate_handler to not "terminate execution of the program without returning to the caller". In implementations I'm familiar with, if the terminate_handler attempts to return, either normally, or exceptionally, abort() will be called.

Q3

The function set by std::terminate is a global, not a thread local. So one thread can impact another.

In C++98/03, the terminate_handler used when terminate is called due to an uncaught exception is the one that was in effect when the exception was thrown, not the one in effect when terminate is actually called (though they are usually the same).

In C++11 this was changed and the standard now says that the handler used is the one in place at the time terminate is called. This change was done by mistake and will most likely be corrected in a future draft. Here is the LWG issue tracking this issue:

http://cplusplus.github.com/LWG/lwg-active.html#2111

Update

At the Spring 2015 meeting in Lenexa, KS, the LWG decided to standardize existing behavior and made it unspecified when a new terminate_handler goes into effect if set_terminate is called during stack unwinding. I.e. implementations are allowed to follow either the C++98/03 rules or the C++11 rules.

To make your code portable, if you need to set a terminate_handler, do so during program startup, before any exceptions will be thrown, and do not make a habit of calling set_terminate after that.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • +1. Just to answer question in subject: user provided terminate function must be thread safe? What about other "on disaster" functions? What about new_handler? Is this gcc advice dangerous of being double delete: http://gcc.gnu.org/onlinedocs/libstdc++/manual/dynamic_memory.html? – PiotrNycz Oct 27 '12 at 22:33
  • Since `std::terminate` can be called concurrently, the `terminate_handler` should be thread safe. And the same is true of all other handlers specified in the standard, including `new_handler`. Yes, the gcc example is in danger of performing a double delete. This could be solved with an atomic exchange on `safety`. – Howard Hinnant Oct 27 '12 at 22:58
  • "function set by std::set_terminate is a global" - Why? Some implementations says it is local ([ms:terminate functions are maintained separately for each thread](http://msdn.microsoft.com/en-us/library/aa272914(v=vs.60).aspx); [ibm:You can override this with a thread-level termination](http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.bpxbd00/setterm.htm);[sun:thread can set its own](http://www.amath.unc.edu/sysadmin/DOC4.0/c-plusplus/c%2B%2B_ug/Exception_Handling.doc.html)) Can't find exact definition in the standard.http://stackoverflow.com/q/15367060/196561 – osgx Mar 12 '13 at 16:49