#include #include #include "syscall.h" #include "pthread_impl.h" #include "atomic.h" #include "lock.h" #include "ksigaction.h" #if __EMSCRIPTEN__ #include "emscripten_internal.h" #endif _Noreturn void abort(void) { #if __EMSCRIPTEN__ /* In emscripten we call out to JS to perform the actual abort where it can * produce a nice error. * Note that the JS library function is not called `abort` to avoid conflict * with the JavaScript abort helper (which takes a JS string as an argument * and is itself used to implement `_abort_js`) */ _abort_js(); #else raise(SIGABRT); /* If there was a SIGABRT handler installed and it returned, or if * SIGABRT was blocked or ignored, take an AS-safe lock to prevent * sigaction from installing a new SIGABRT handler, uninstall any * handler that may be present, and re-raise the signal to generate * the default action of abnormal termination. */ __block_all_sigs(0); LOCK(__abort_lock); __syscall(SYS_rt_sigaction, SIGABRT, &(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8); __syscall(SYS_tkill, __pthread_self()->tid, SIGABRT); __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, &(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8); /* Beyond this point should be unreachable. */ a_crash(); raise(SIGKILL); _Exit(127); #endif }