| //===-- Internal header for Linux abort -------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H |
| #define LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H |
| |
| #include "hdr/types/sigset_t.h" |
| #include "hdr/types/struct_sigaction.h" |
| #include "src/__support/OSUtil/exit.h" |
| #include "src/__support/OSUtil/linux/syscall_wrappers/raise.h" |
| #include "src/__support/common.h" |
| #include "src/__support/macros/config.h" |
| #include "src/signal/linux/signal_utils.h" |
| |
| namespace LIBC_NAMESPACE_DECL { |
| |
| namespace abort_utils { |
| [[noreturn]] LIBC_INLINE void abort() { |
| // Try to raise SIGABRT. |
| // If this fails, or if a handler returns, keep going with the hard-abort |
| // sequence below. |
| linux_syscalls::raise(SIGABRT); |
| |
| // We get back from abort, potentially from a abort handler. |
| // We recover the handler to default and raise it again. Since this is the |
| // real abort routine, we demand exclusive access to the abort lock. |
| // We have already returned from the first raise, so it is okay to grab |
| // exclusive access. |
| SigAbortGuard guard(true); |
| struct sigaction sa{}; |
| sa.sa_handler = SIG_DFL; |
| sa.sa_flags = 0; |
| // There is no recovery path from sigaction failure while aborting. |
| unchecked_sigaction(SIGABRT, &sa, nullptr); |
| // If this still returns, fall through to the final termination path. |
| linux_syscalls::raise(SIGABRT); |
| |
| // Now unblock the signal. The pending abort signal is now unblocked and |
| // should be delivered to its default handler. |
| // If this fails, there is still no meaningful recovery path while aborting. |
| unblock_signal(SIGABRT); |
| |
| internal::exit(127); |
| } |
| } // namespace abort_utils |
| |
| } // namespace LIBC_NAMESPACE_DECL |
| |
| #endif // LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H |