55 lines
2.0 KiB
C++
55 lines
2.0 KiB
C++
//===-- 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
|