浏览代码

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.
Sergey Bugaev 5 年之前
父节点
当前提交
839ae82d66
共有 1 个文件被更改,包括 4 次插入1 次删除
  1. 4 1
      Libraries/LibC/stdlib.cpp

+ 4 - 1
Libraries/LibC/stdlib.cpp

@@ -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;