This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 3b38ca7861a212ad8a559c26266af6ac08258f77
Author: ligd <[email protected]>
AuthorDate: Wed Nov 11 16:14:25 2026 +0800

    sched: check TCB_FLAG_EXIT_PROCESSING to avoid exit twice
    
    TCB_FLAG_EXIT_PROCESSING was set by nx_pthread_exit() only after the
    join handshake completed, so during the handshake the exiting thread
    was not yet marked as exiting: checks that rely on the flag, such as
    the one in nxsig_tcbdispatch(), did not cover that window, and a fatal
    signal handled in the window re-entered the exit path through
    nxsig_abnormal_termination() and terminated the thread twice.
    
    Set the flag at the top of nx_pthread_exit(), before the join
    handshake, so the whole exit is visible to the existing checks, and
    make nxsig_abnormal_termination() return early when the flag is
    already set so an action that is already in flight cannot drive the
    terminating thread through the exit path a second time.
    
    Signed-off-by: ligd <[email protected]>
    Signed-off-by: zhangyuan29 <[email protected]>
---
 sched/pthread/pthread_exit.c | 4 ++--
 sched/signal/sig_default.c   | 9 +++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c
index 3650dff0ddd..9a25815997d 100644
--- a/sched/pthread/pthread_exit.c
+++ b/sched/pthread/pthread_exit.c
@@ -74,6 +74,8 @@ void nx_pthread_exit(FAR void *exit_value)
 
   DEBUGASSERT(tcb != NULL);
 
+  tcb->flags |= TCB_FLAG_EXIT_PROCESSING;
+
   /* Block any signal actions that would awaken us while were
    * are performing the JOIN handshake.
    */
@@ -113,8 +115,6 @@ void nx_pthread_exit(FAR void *exit_value)
    * once, or does something very naughty.
    */
 
-  tcb->flags |= TCB_FLAG_EXIT_PROCESSING;
-
   nxtask_exithook(tcb, status);
 
   up_exit(EXIT_SUCCESS);
diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c
index f52a148ed3c..ea556541190 100644
--- a/sched/signal/sig_default.c
+++ b/sched/signal/sig_default.c
@@ -237,6 +237,15 @@ static void nxsig_abnormal_termination(int signo)
   group_kill_children(rtcb);
 #endif
 
+  if ((rtcb->flags & TCB_FLAG_EXIT_PROCESSING) != 0)
+    {
+      /* If we are already in the process of terminating, then we should
+       * not be here.  We should have already exited.
+       */
+
+      return;
+    }
+
 #ifndef CONFIG_DISABLE_PTHREAD
   /* Check if the currently running task is actually a pthread */
 

Reply via email to