[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