[libc-commits] [libc] [libc][thread] detect self-join and mutual-join deadlock (PR #194891)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Wed Apr 29 08:52:27 PDT 2026
https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/194891
>From a5df0d4cbfd8a959267b4066ce6866ce72532a13 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 29 Apr 2026 11:42:01 -0400
Subject: [PATCH 1/4] [libc][thread] detect self-join and mutual-join deadlock
---
libc/src/__support/threads/linux/thread.cpp | 11 +++++++++++
libc/src/__support/threads/thread.h | 3 ++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 4f1e9110457d9..4199ee78297e7 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -17,6 +17,7 @@
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h" // For FutexWordType
+#include <cerrno>
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
#include <arm_acle.h>
@@ -340,6 +341,16 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
}
int Thread::join(ThreadReturnValue &retval) {
+ if (self.attrib) {
+ // reject self join or invalid thread
+ if (self.attrib == attrib)
+ return EDEADLK;
+
+ // reject mutual join
+ if (attrib->joiner.exchange(self.attrib) == self.attrib->joiner)
+ return EDEADLK;
+ }
+
wait();
if (attrib->style == ThreadStyle::POSIX)
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 6806098653b2c..232b300bbba5b 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -109,12 +109,13 @@ struct alignas(STACK_ALIGNMENT) ThreadAttributes {
ThreadReturnValue retval;
ThreadAtExitCallbackMgr *atexit_callback_mgr;
void *platform_data;
+ cpp::Atomic<ThreadAttributes *> joiner;
LIBC_INLINE constexpr ThreadAttributes()
: detach_state(uint32_t(DetachState::DETACHED)), stack(nullptr),
stacksize(0), guardsize(0), tls(0), tls_size(0), owned_stack(false),
tid(-1), style(ThreadStyle::POSIX), retval(),
- atexit_callback_mgr(nullptr), platform_data(nullptr) {}
+ atexit_callback_mgr(nullptr), platform_data(nullptr), joiner(nullptr) {}
};
using TSSDtor = void(void *);
>From f9a086d90c54285c95e38c316bd2bceb3c751f1f Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 29 Apr 2026 11:47:05 -0400
Subject: [PATCH 2/4] fix
---
libc/src/__support/threads/linux/CMakeLists.txt | 1 +
libc/src/__support/threads/linux/thread.cpp | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt
index 5bd67c60ad88b..b9273b42bb5f1 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -33,6 +33,7 @@ add_object_library(
libc.config.app_h
libc.include.sys_syscall
libc.hdr.fcntl_macros
+ libc.hdr.errno_macros
libc.src.errno.errno
libc.src.__support.CPP.atomic
libc.src.__support.CPP.stringstream
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 4199ee78297e7..2ec796d0c7f37 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -17,13 +17,13 @@
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h" // For FutexWordType
-#include <cerrno>
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
#include <arm_acle.h>
#endif
#include "hdr/fcntl_macros.h"
+#include "hdr/errno_macros.h"
#include "hdr/stdint_proxy.h"
#include <linux/param.h> // For EXEC_PAGESIZE.
#include <linux/prctl.h> // For PR_SET_NAME
>From cd3de9b633b9b2e114b3b6f2285c33e6f3d4f156 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 29 Apr 2026 11:47:53 -0400
Subject: [PATCH 3/4] fix
---
libc/src/__support/threads/linux/thread.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 2ec796d0c7f37..d568b337ae37f 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -342,7 +342,7 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
int Thread::join(ThreadReturnValue &retval) {
if (self.attrib) {
- // reject self join or invalid thread
+ // reject self join
if (self.attrib == attrib)
return EDEADLK;
>From a2bcd831e48ebdc75fddb43811f87a6edd3436dd Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 29 Apr 2026 11:52:12 -0400
Subject: [PATCH 4/4] fmt
---
libc/src/__support/threads/linux/thread.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index d568b337ae37f..b7eae62120271 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -22,8 +22,8 @@
#include <arm_acle.h>
#endif
-#include "hdr/fcntl_macros.h"
#include "hdr/errno_macros.h"
+#include "hdr/fcntl_macros.h"
#include "hdr/stdint_proxy.h"
#include <linux/param.h> // For EXEC_PAGESIZE.
#include <linux/prctl.h> // For PR_SET_NAME
More information about the libc-commits
mailing list