[libc-commits] [libc] [libc] update abort implementation and lift it for internal usage (PR #189756)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Wed Apr 1 07:51:32 PDT 2026
https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/189756
>From 60be7798c2844812a54471013645ed3558fef8cc Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Tue, 31 Mar 2026 17:39:31 -0400
Subject: [PATCH 1/5] [libc] update abort implementation and lift it for
internal usage
---
libc/src/signal/linux/signal_utils.h | 8 ++
libc/src/stdlib/linux/CMakeLists.txt | 16 +++-
libc/src/stdlib/linux/abort.cpp | 19 +---
libc/src/stdlib/linux/abort_utils.h | 78 ++++++++++++++++
.../integration/src/stdlib/CMakeLists.txt | 23 +++++
.../integration/src/stdlib/abort_test.cpp | 89 +++++++++++++++++++
6 files changed, 214 insertions(+), 19 deletions(-)
create mode 100644 libc/src/stdlib/linux/abort_utils.h
create mode 100644 libc/test/integration/src/stdlib/abort_test.cpp
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index be4501c27dba5..e36d47f4fb602 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -113,6 +113,14 @@ LIBC_INLINE int restore_signals(const sigset_t &set) {
&set, nullptr, sizeof(sigset_t));
}
+LIBC_INLINE int unblock_signal(int signal) {
+ sigset_t set;
+ if (!add_signal(set, signal))
+ return -EINVAL;
+ return LIBC_NAMESPACE::syscall_impl<int>(SYS_rt_sigprocmask, SIG_UNBLOCK,
+ &set, nullptr, sizeof(sigset_t));
+}
+
LIBC_INLINE ErrorOr<int>
do_sigaction(int signal, const struct sigaction *__restrict libc_new,
struct sigaction *__restrict libc_old) {
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index 1d3c00a5e0ddb..4e476d8d57354 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -1,3 +1,15 @@
+add_header_library(
+ abort_utils
+ HDRS
+ abort_utils.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.signal.raise
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.threads.linux.rwlock
+ libc.src.signal.linux.__restore
+)
+
add_entrypoint_object(
abort
SRCS
@@ -5,7 +17,7 @@ add_entrypoint_object(
HDRS
../abort.h
DEPENDS
+ .abort_utils
+ libc.src.signal.linux.__restore
libc.include.stdlib
- libc.src.signal.raise
- libc.src.stdlib._Exit
)
diff --git a/libc/src/stdlib/linux/abort.cpp b/libc/src/stdlib/linux/abort.cpp
index d78ea675593a4..0374e9315cba8 100644
--- a/libc/src/stdlib/linux/abort.cpp
+++ b/libc/src/stdlib/linux/abort.cpp
@@ -6,26 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/signal/raise.h"
-#include "src/stdlib/_Exit.h"
-
#include "src/stdlib/abort.h"
+#include "src/stdlib/linux/abort_utils.h"
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(void, abort, ()) {
- // TODO: When sigprocmask and sigaction land:
- // Unblock SIGABRT, raise it, if it was ignored or the handler returned,
- // change its action to SIG_DFL, raise it again.
- // TODO: When C11 mutexes land:
- // Acquire recursive mutex (in case the current signal handler for SIGABRT
- // itself calls abort we don't want to deadlock on the same thread trying
- // to acquire it's own mutex.)
- LIBC_NAMESPACE::raise(SIGABRT);
- LIBC_NAMESPACE::raise(SIGKILL);
- LIBC_NAMESPACE::_Exit(127);
-}
+LLVM_LIBC_FUNCTION(void, abort, ()) { abort_utils::abort(); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/linux/abort_utils.h b/libc/src/stdlib/linux/abort_utils.h
new file mode 100644
index 0000000000000..c4795c879ae08
--- /dev/null
+++ b/libc/src/stdlib/linux/abort_utils.h
@@ -0,0 +1,78 @@
+//===-- 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 "include/llvm-libc-types/sigset_t.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/raise.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/linux/rwlock.h"
+#include "src/signal/linux/signal_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace abort_utils {
+
+// TODO: this lock needs to be acquired during _Fork/fork.
+class AbortLockGuard {
+private:
+ sigset_t old_mask;
+ LIBC_INLINE_VAR static RwLock abort_lock;
+
+public:
+ LIBC_INLINE constexpr AbortLockGuard(bool exclusive) : old_mask{} {
+ RwLock::LockResult result = RwLock::LockResult::Success;
+ do {
+ if (exclusive)
+ result = abort_lock.write_lock(cpp::nullopt);
+ else
+ result = abort_lock.read_lock(cpp::nullopt);
+ } while (result == RwLock::LockResult::Overflow);
+
+ (void)block_all_signals(old_mask);
+ }
+
+ LIBC_INLINE ~AbortLockGuard() {
+ (void)restore_signals(old_mask);
+ (void)abort_lock.unlock();
+ }
+};
+
+[[noreturn]] LIBC_INLINE void abort() {
+ // 1. Try to raise SIGABRT.
+ (void)LIBC_NAMESPACE::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.
+ AbortLockGuard guard(true);
+ struct sigaction sa{};
+ sa.sa_handler = SIG_DFL;
+ sa.sa_flags = 0;
+ (void)do_sigaction(SIGABRT, &sa, nullptr);
+ (void)LIBC_NAMESPACE::linux_syscalls::raise(SIGABRT);
+
+ // Now unblock the signal. The pending abort signal is now unblocked and
+ // should be delivered to its default handler.
+ (void)unblock_signal(SIGABRT);
+
+ LIBC_NAMESPACE::internal::exit(127);
+}
+} // namespace abort_utils
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H
diff --git a/libc/test/integration/src/stdlib/CMakeLists.txt b/libc/test/integration/src/stdlib/CMakeLists.txt
index 1773d9fc9f0f5..cf39b7ceb2f87 100644
--- a/libc/test/integration/src/stdlib/CMakeLists.txt
+++ b/libc/test/integration/src/stdlib/CMakeLists.txt
@@ -16,3 +16,26 @@ add_integration_test(
FRANCE=Paris
GERMANY=Berlin
)
+
+if(${LIBC_TARGET_OS} STREQUAL "linux")
+ add_integration_test(
+ abort_test
+ SUITE
+ stdlib-integration-tests
+ SRCS
+ abort_test.cpp
+ DEPENDS
+ libc.include.signal
+ libc.include.sys_wait
+ libc.include.unistd
+ libc.src.signal.signal
+ libc.src.stdlib._Exit
+ libc.src.stdlib.abort
+ libc.src.sys.wait.waitpid
+ libc.src.unistd.close
+ libc.src.unistd.fork
+ libc.src.unistd.pipe
+ libc.src.unistd.read
+ libc.src.unistd.write
+ )
+endif()
diff --git a/libc/test/integration/src/stdlib/abort_test.cpp b/libc/test/integration/src/stdlib/abort_test.cpp
new file mode 100644
index 0000000000000..5b8a38655ef8c
--- /dev/null
+++ b/libc/test/integration/src/stdlib/abort_test.cpp
@@ -0,0 +1,89 @@
+//===-- Integration tests for abort --------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/signal/signal.h"
+#include "src/stdlib/_Exit.h"
+#include "src/stdlib/abort.h"
+#include "src/stdlib/linux/abort_utils.h"
+#include "src/sys/wait/waitpid.h"
+#include "src/unistd/close.h"
+#include "src/unistd/fork.h"
+#include "src/unistd/pipe.h"
+#include "src/unistd/read.h"
+#include "src/unistd/write.h"
+
+#include "test/IntegrationTest/test.h"
+
+#include <signal.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace {
+
+constexpr char HANDLER_MARKER = 'A';
+int handler_pipe_fd = -1;
+
+void expect_child_died_with_signal(pid_t pid, int signal) {
+ int status = 0;
+ ASSERT_EQ(LIBC_NAMESPACE::waitpid(pid, &status, 0), pid);
+ ASSERT_TRUE(WIFSIGNALED(status));
+ ASSERT_EQ(WTERMSIG(status), signal);
+}
+
+void child_abort() { LIBC_NAMESPACE::abort(); }
+
+void returning_sigabrt_handler(int) {
+ if (handler_pipe_fd >= 0)
+ LIBC_NAMESPACE::write(handler_pipe_fd, &HANDLER_MARKER, 1);
+}
+
+void child_abort_with_returning_handler() {
+ auto previous = LIBC_NAMESPACE::signal(SIGABRT, returning_sigabrt_handler);
+ ASSERT_NE(previous, SIG_ERR);
+ LIBC_NAMESPACE::abort();
+}
+
+void abort_kills_child_with_sigabrt() {
+ pid_t pid = LIBC_NAMESPACE::fork();
+ if (pid == 0)
+ child_abort();
+
+ ASSERT_TRUE(pid > 0);
+ expect_child_died_with_signal(pid, SIGABRT);
+}
+
+void abort_reraises_sigabrt_after_returning_handler() {
+ int pipefd[2];
+ ASSERT_EQ(LIBC_NAMESPACE::pipe(pipefd), 0);
+
+ pid_t pid = LIBC_NAMESPACE::fork();
+ if (pid == 0) {
+ LIBC_NAMESPACE::close(pipefd[0]);
+ handler_pipe_fd = pipefd[1];
+ child_abort_with_returning_handler();
+ }
+
+ ASSERT_TRUE(pid > 0);
+ ASSERT_EQ(LIBC_NAMESPACE::close(pipefd[1]), 0);
+
+ expect_child_died_with_signal(pid, SIGABRT);
+
+ char marker = 0;
+ ASSERT_EQ(LIBC_NAMESPACE::read(pipefd[0], &marker, 1), ssize_t(1));
+ ASSERT_EQ(marker, HANDLER_MARKER);
+ ASSERT_EQ(LIBC_NAMESPACE::close(pipefd[0]), 0);
+}
+
+} // namespace
+
+TEST_MAIN([[maybe_unused]] int argc, [[maybe_unused]] char **argv,
+ [[maybe_unused]] char **envp) {
+ abort_kills_child_with_sigabrt();
+ abort_reraises_sigabrt_after_returning_handler();
+ return 0;
+}
>From 87eb626c1a325625b8fd8e8200db8173fc3ac249 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 1 Apr 2026 10:17:51 -0400
Subject: [PATCH 2/5] fix
---
libc/src/stdlib/linux/CMakeLists.txt | 2 +-
libc/src/stdlib/linux/abort_utils.h | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index 4e476d8d57354..ca09842fa906d 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -6,7 +6,7 @@ add_header_library(
libc.include.stdlib
libc.src.signal.raise
libc.src.__support.OSUtil.osutil
- libc.src.__support.threads.linux.rwlock
+ libc.src.__support.threads.raw_rwlock
libc.src.signal.linux.__restore
)
diff --git a/libc/src/stdlib/linux/abort_utils.h b/libc/src/stdlib/linux/abort_utils.h
index c4795c879ae08..5e686f0c3475a 100644
--- a/libc/src/stdlib/linux/abort_utils.h
+++ b/libc/src/stdlib/linux/abort_utils.h
@@ -17,7 +17,7 @@
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/threads/linux/rwlock.h"
+#include "src/__support/threads/raw_rwlock.h"
#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -28,17 +28,17 @@ namespace abort_utils {
class AbortLockGuard {
private:
sigset_t old_mask;
- LIBC_INLINE_VAR static RwLock abort_lock;
+ LIBC_INLINE_VAR static RawRwLock abort_lock;
public:
LIBC_INLINE constexpr AbortLockGuard(bool exclusive) : old_mask{} {
- RwLock::LockResult result = RwLock::LockResult::Success;
+ RawRwLock::LockResult result = RawRwLock::LockResult::Success;
do {
if (exclusive)
result = abort_lock.write_lock(cpp::nullopt);
else
result = abort_lock.read_lock(cpp::nullopt);
- } while (result == RwLock::LockResult::Overflow);
+ } while (result == RawRwLock::LockResult::Overflow);
(void)block_all_signals(old_mask);
}
>From ac8cc59295cfa2c691bf12e0b247034e9a75815c Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 1 Apr 2026 10:18:46 -0400
Subject: [PATCH 3/5] fix trivial auto var
---
libc/src/signal/linux/signal_utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index e36d47f4fb602..66e55943a2c3f 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -114,7 +114,7 @@ LIBC_INLINE int restore_signals(const sigset_t &set) {
}
LIBC_INLINE int unblock_signal(int signal) {
- sigset_t set;
+ sigset_t set = empty_set();
if (!add_signal(set, signal))
return -EINVAL;
return LIBC_NAMESPACE::syscall_impl<int>(SYS_rt_sigprocmask, SIG_UNBLOCK,
>From 0086fb5b41a88a8699a458a4b817269016ad9f4d Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 1 Apr 2026 10:41:43 -0400
Subject: [PATCH 4/5] fix
---
libc/src/signal/linux/CMakeLists.txt | 1 +
libc/src/signal/linux/sigaction.cpp | 2 +-
libc/src/signal/linux/signal_utils.h | 46 ++++++++++++++++++++++++++--
libc/src/stdlib/linux/CMakeLists.txt | 1 -
libc/src/stdlib/linux/abort_utils.h | 35 ++-------------------
5 files changed, 49 insertions(+), 36 deletions(-)
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index 44c41737b89b0..45ffb6994573b 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -11,6 +11,7 @@ add_header_library(
libc.src.__support.OSUtil.linux.vdso
libc.src.__support.OSUtil.osutil
libc.src.__support.error_or
+ libc.src.__support.threads.raw_rwlock
)
add_entrypoint_object(
diff --git a/libc/src/signal/linux/sigaction.cpp b/libc/src/signal/linux/sigaction.cpp
index 9e76c188ed440..c763718278467 100644
--- a/libc/src/signal/linux/sigaction.cpp
+++ b/libc/src/signal/linux/sigaction.cpp
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, sigaction,
(int signal, const struct sigaction *__restrict libc_new,
struct sigaction *__restrict libc_old)) {
- ErrorOr<int> ret = do_sigaction(signal, libc_new, libc_old);
+ ErrorOr<int> ret = checked_sigaction(signal, libc_new, libc_old);
if (ret)
return ret.value();
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index 66e55943a2c3f..d7eb55f1be9f5 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -19,6 +19,7 @@
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
+#include "src/__support/threads/raw_rwlock.h"
#include <sys/syscall.h> // For syscall numbers.
@@ -121,9 +122,38 @@ LIBC_INLINE int unblock_signal(int signal) {
&set, nullptr, sizeof(sigset_t));
}
+// This guard is used to:
+// 1. temporarily block the all signal, avoid post fork invalid state to be
+// exposed to async signal handlers.
+// 2. ensure the ordering between sigaction and fork/spawn, so that forked
+// processes can see modification from a just returned concurrent call.
+class SigAbortGuard {
+private:
+ sigset_t old_mask;
+ LIBC_INLINE_VAR static RawRwLock abort_lock;
+
+public:
+ LIBC_INLINE constexpr SigAbortGuard(bool exclusive) : old_mask{} {
+ RawRwLock::LockResult result = RawRwLock::LockResult::Success;
+ do {
+ if (exclusive)
+ result = abort_lock.write_lock(cpp::nullopt);
+ else
+ result = abort_lock.read_lock(cpp::nullopt);
+ } while (result == RawRwLock::LockResult::Overflow);
+
+ (void)block_all_signals(old_mask);
+ }
+
+ LIBC_INLINE ~SigAbortGuard() {
+ (void)restore_signals(old_mask);
+ (void)abort_lock.unlock();
+ }
+};
+
LIBC_INLINE ErrorOr<int>
-do_sigaction(int signal, const struct sigaction *__restrict libc_new,
- struct sigaction *__restrict libc_old) {
+unchecked_sigaction(int signal, const struct sigaction *__restrict libc_new,
+ struct sigaction *__restrict libc_old) {
vdso::TypedSymbol<vdso::VDSOSym::RTSigReturn> rt_sigreturn;
KernelSigaction kernel_new;
if (libc_new) {
@@ -146,6 +176,18 @@ do_sigaction(int signal, const struct sigaction *__restrict libc_new,
return 0;
}
+LIBC_INLINE ErrorOr<int>
+checked_sigaction(int signal, const struct sigaction *__restrict libc_new,
+ struct sigaction *__restrict libc_old) {
+ if (signal <= 0 || signal >= NSIG)
+ return Error(-EINVAL);
+ if (signal == SIGABRT) {
+ SigAbortGuard guard(true);
+ return unchecked_sigaction(signal, libc_new, libc_old);
+ }
+ return unchecked_sigaction(signal, libc_new, libc_old);
+}
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index ca09842fa906d..ac739abba0c26 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -6,7 +6,6 @@ add_header_library(
libc.include.stdlib
libc.src.signal.raise
libc.src.__support.OSUtil.osutil
- libc.src.__support.threads.raw_rwlock
libc.src.signal.linux.__restore
)
diff --git a/libc/src/stdlib/linux/abort_utils.h b/libc/src/stdlib/linux/abort_utils.h
index 5e686f0c3475a..daf47e1f08fa6 100644
--- a/libc/src/stdlib/linux/abort_utils.h
+++ b/libc/src/stdlib/linux/abort_utils.h
@@ -10,45 +10,16 @@
#define LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H
#include "hdr/types/sigset_t.h"
-#include "include/llvm-libc-types/sigset_t.h"
-#include "src/__support/CPP/optional.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/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/threads/raw_rwlock.h"
#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
namespace abort_utils {
-
-// TODO: this lock needs to be acquired during _Fork/fork.
-class AbortLockGuard {
-private:
- sigset_t old_mask;
- LIBC_INLINE_VAR static RawRwLock abort_lock;
-
-public:
- LIBC_INLINE constexpr AbortLockGuard(bool exclusive) : old_mask{} {
- RawRwLock::LockResult result = RawRwLock::LockResult::Success;
- do {
- if (exclusive)
- result = abort_lock.write_lock(cpp::nullopt);
- else
- result = abort_lock.read_lock(cpp::nullopt);
- } while (result == RawRwLock::LockResult::Overflow);
-
- (void)block_all_signals(old_mask);
- }
-
- LIBC_INLINE ~AbortLockGuard() {
- (void)restore_signals(old_mask);
- (void)abort_lock.unlock();
- }
-};
-
[[noreturn]] LIBC_INLINE void abort() {
// 1. Try to raise SIGABRT.
(void)LIBC_NAMESPACE::linux_syscalls::raise(SIGABRT);
@@ -58,11 +29,11 @@ class AbortLockGuard {
// 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.
- AbortLockGuard guard(true);
+ SigAbortGuard guard(true);
struct sigaction sa{};
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
- (void)do_sigaction(SIGABRT, &sa, nullptr);
+ (void)unchecked_sigaction(SIGABRT, &sa, nullptr);
(void)LIBC_NAMESPACE::linux_syscalls::raise(SIGABRT);
// Now unblock the signal. The pending abort signal is now unblocked and
>From 88e6368687ea76544c9605083d70ac03a0972deb Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 1 Apr 2026 10:51:16 -0400
Subject: [PATCH 5/5] fix deps and test
---
libc/src/signal/linux/signal_utils.h | 2 +-
libc/src/stdlib/linux/CMakeLists.txt | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index d7eb55f1be9f5..bb9b6593f9f4b 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -180,7 +180,7 @@ LIBC_INLINE ErrorOr<int>
checked_sigaction(int signal, const struct sigaction *__restrict libc_new,
struct sigaction *__restrict libc_old) {
if (signal <= 0 || signal >= NSIG)
- return Error(-EINVAL);
+ return Error(EINVAL);
if (signal == SIGABRT) {
SigAbortGuard guard(true);
return unchecked_sigaction(signal, libc_new, libc_old);
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index ac739abba0c26..6f52acdc856ac 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -3,10 +3,10 @@ add_header_library(
HDRS
abort_utils.h
DEPENDS
- libc.include.stdlib
- libc.src.signal.raise
+ libc.src.__support.OSUtil.linux.syscall_wrappers.raise
libc.src.__support.OSUtil.osutil
libc.src.signal.linux.__restore
+ libc.src.signal.linux.signal_utils
)
add_entrypoint_object(
More information about the libc-commits
mailing list