LibC: Ensure abort() doesn't return

It's not enough to send ourselves a SIGABRT, as it may be ignored or handled
differently. We really, really want abort() to never return, as that will mess
up the assumptions of the calling code big time. So, if raise(SIGABRT) returns,
kill ourselves with SIGKILL, and if that somehow returns too, call _exit().

An alternative approach, which glibc apparently follows, is to reset SIGABRT
disposition to its default value and then send SIGABRT to yourself a second
time. That would also work, but I believe SIGKILL + _exit() to be a simpler
approach that is less likely to break in extremely weird situations.

Note that this only guarantees that abort() never returns, not that the process
actually gets killed. It's still possible to install a SIGABRT handler that
simply never returns (such as by longjmp'ing out, endlessly looping, or exec'ing
another image). That is a legitimate use case we want to support; at the same
time most software doesn't use that functionality and would benefit from hard
guarantees that abort() terminates the program. The following commit is going to
introduce means for ensuring SIGABRT handler is never reset to something
unexpected.
This commit is contained in:
Sergey Bugaev 2020-05-26 13:15:59 +03:00 committed by Andreas Kling
parent ac4a31e057
commit 839ae82d66
Notes: sideshowbarker 2024-07-19 06:07:12 +09:00

View file

@ -222,8 +222,11 @@ int atexit(void (*handler)())
void abort()
{
// For starters, send ourselves a SIGABRT.
raise(SIGABRT);
ASSERT_NOT_REACHED();
// If that didn't kill us, try harder.
raise(SIGKILL);
_exit(127);
}
static HashTable<const char*> s_malloced_environment_variables;