I have some clean up in a terminate_handler and it is possible to throw an exception. Do I need to worry about catching it to prevent recursive calls to the terminate_handler? With gcc, it seems this can't happen and we just go into abort. Is that true of the standard or is the behavior undefined?
No, you cannot resume normal program flow from std::terminate
. You can, however, throw a different exception from the unexpected
function. Terminate
does just that -- program execution terminates after it completes.
EDIT:
That said, you shouldn't be doing anything complicated in std::terminate
-- if you're in terminate
then things have blown up sufficiently that you should not be trying to continue -- and you shouldn't try to do things like allocate memory in std::terminate
for the same reason -- what if the program is in there as a result of a low memory condition? There's nothing you can do about it there.
A terminate handler is not allowed to return (§18.6.3.1/2); it must end the program (the default handler calls abort()
). If it consisted of:
void my_terminate()
{
throw 5;
}
You'd get undefined behavior, because you would leave the function (because the exception propagates) without having terminated the program. So if you have code that could throw, make sure you catch all exceptions, like this:
void my_terminate()
{
try
{
// stuff
}
catch(...)
{
// too bad
}
abort();
}
However (to answer the title question), I don't see anything that restricts it from being entered again, so this should be technically be fine:
void my_terminate()
{
static int counter = 0;
if (counter++ < 5)
terminate();
abort();
}