Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 1/2] [gdb/testsuite] Fix race in gdb.threads/leader-exit.exp
Date: Fri, 24 Jul 2026 04:44:26 +0200	[thread overview]
Message-ID: <20260724024427.752545-2-tdevries@suse.de> (raw)
In-Reply-To: <20260724024427.752545-1-tdevries@suse.de>

On aarch64-linux, when running test-case gdb.threads/leader-exit.exp with
"taskset -c 0", 3 out of 10 times I run into:
...
(gdb) continue
Continuing.
[New Thread 0xfffff7d1f160 (LWP 62010) (id 2)]
[Switching to thread 2 (Thread 0xfffff7d1f160 (LWP 62010))]

Thread 2 "leader-exit" hit Breakpoint 2, start (arg=0x0) at leader-exit.c:32
32        sleep (10);  /* break-here */
(gdb) PASS: gdb.threads/leader-exit.exp: continue to breakpoint: break-here
info threads
  Id   Target Id                                                 Frame
  1    Thread 0xfffff7fe8020 (LWP 62008) "leader-exit" (Exiting) \
         0x0000fffff7d46fa0 in __libc_start_call_main () from /lib64/libc.so.6
* 2    Thread 0xfffff7d1f160 (LWP 62010) "leader-exit" \
         start (arg=0x0) at leader-exit.c:32
(gdb) FAIL: gdb.threads/leader-exit.exp: single thread has been left
...

In a passing version, the continue produces a "Thread exited" message, but
that's missing here.

The problem is that after the pthread_join is executed:
...
  i = pthread_join (main_thread, NULL);
  ...

  sleep (10);  /* break-here */
...
there's a race between:
- the breakpoint at break-here triggering, and
- the "Thread exited" message for the main thread being reported.

Fix this by:
- adding a loop before the break location
- waiting in the loop until the "Thread exited" message is seen
- sending ^C to get a prompt
- setting a variable to exit the loop

Likewise in gdb.threads/non-ldr-exc-2.exp.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34425
---
 gdb/testsuite/gdb.threads/leader-exit.c     |  4 ++++
 gdb/testsuite/gdb.threads/leader-exit.exp   | 24 ++++++++++++++++++++-
 gdb/testsuite/gdb.threads/non-ldr-exc-2.c   |  5 +++++
 gdb/testsuite/gdb.threads/non-ldr-exc-2.exp | 24 ++++++++++++++++++++-
 4 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.threads/leader-exit.c b/gdb/testsuite/gdb.threads/leader-exit.c
index bd546d009cd..b24817e8a14 100644
--- a/gdb/testsuite/gdb.threads/leader-exit.c
+++ b/gdb/testsuite/gdb.threads/leader-exit.c
@@ -21,6 +21,8 @@
 
 static volatile pthread_t main_thread;
 
+static volatile int wait_for_exit = 1;
+
 static void *
 start (void *arg)
 {
@@ -28,6 +30,8 @@ start (void *arg)
 
   i = pthread_join (main_thread, NULL);
   assert (i == 0);
+  while (wait_for_exit)
+    usleep (100 * 1000);
 
   sleep (10);  /* break-here */
   return arg;
diff --git a/gdb/testsuite/gdb.threads/leader-exit.exp b/gdb/testsuite/gdb.threads/leader-exit.exp
index b5e6f558ac7..e53f4cacece 100644
--- a/gdb/testsuite/gdb.threads/leader-exit.exp
+++ b/gdb/testsuite/gdb.threads/leader-exit.exp
@@ -30,7 +30,29 @@ if {![runto_main]} {
     return
 }
 
-gdb_breakpoint [gdb_get_line_number "break-here"]
+# Wait for the "Thread exited" message.
+set re_thread_exited {\[Thread [^\r\n]+ exited\]}
+set saw_thread_exited 0
+gdb_test_multiple "continue" "continue to thread exited" {
+    -re $re_thread_exited {
+	set saw_thread_exited 1
+	# Get a prompt.
+	send_gdb "\003"
+	exp_continue
+    }
+    -re -wrap "" {
+	pass $gdb_test_name
+    }
+}
+gdb_assert {$saw_thread_exited} "thread exited"
+if {!$saw_thread_exited} {
+    return
+}
+
+# Let the inferior to exit the wait_for_exit loop.
+gdb_test_no_output "set var wait_for_exit = 0"
+
+gdb_breakpoint $srcfile:[gdb_get_line_number "break-here"]
 gdb_continue_to_breakpoint "break-here" ".* break-here .*"
 
 gdb_test "info threads" \
diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-2.c b/gdb/testsuite/gdb.threads/non-ldr-exc-2.c
index b05479be01f..a9e81dfa495 100644
--- a/gdb/testsuite/gdb.threads/non-ldr-exc-2.c
+++ b/gdb/testsuite/gdb.threads/non-ldr-exc-2.c
@@ -26,6 +26,8 @@ static const char *image;
 static volatile pthread_t main_thread;
 static char *argv1 = "go away";
 
+static volatile int wait_for_exit = 1;
+
 static void *
 thread_execler (void *arg)
 {
@@ -34,6 +36,9 @@ thread_execler (void *arg)
   i = pthread_join (main_thread, NULL);
   assert (i == 0);
 
+  while (wait_for_exit)
+    usleep (100 * 1000);
+
   /* Exec ourselves again.  */
   if (execl (image, image, argv1, NULL) == -1) /* break-here */
     {
diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp b/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp
index ead262cc2b5..d21ab1d9a56 100644
--- a/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp
+++ b/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp
@@ -37,7 +37,29 @@ proc do_test { lock_sched nonstop } {
 	return -1
     }
 
-    gdb_breakpoint [gdb_get_line_number "break-here"]
+    # Wait for the "Thread exited" message.
+    set re_thread_exited {\[Thread [^\r\n]+ exited\]}
+    set saw_thread_exited 0
+    gdb_test_multiple "continue" "continue to thread exited" {
+	-re $re_thread_exited {
+	    set saw_thread_exited 1
+	    # Get a prompt.
+	    send_gdb "\003"
+	    exp_continue
+	}
+	-re -wrap "" {
+	    pass $gdb_test_name
+	}
+    }
+    gdb_assert {$saw_thread_exited} "thread exited"
+    if {!$saw_thread_exited} {
+	return
+    }
+
+    # Let the inferior to exit the wait_for_exit loop.
+    gdb_test_no_output "set var wait_for_exit = 0"
+
+    gdb_breakpoint $::srcfile:[gdb_get_line_number "break-here"]
     gdb_continue_to_breakpoint "break-here" ".* break-here .*"
 
     if { $nonstop == "on" } {
-- 
2.51.0


  reply	other threads:[~2026-07-24  2:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-24  2:44 [PATCH v2 0/2] [gdb/testsuite] Two gdb.threads patches Tom de Vries
2026-07-24  2:44 ` Tom de Vries [this message]
2026-07-24  2:44 ` [PATCH v2 2/2] [gdb/testsuite] Fix timeout in gdb.threads/vfork-multi-inferior.exp Tom de Vries
2026-07-25  4:33 ` [PATCH v2 0/2] [gdb/testsuite] Two gdb.threads patches Kevin Buettner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260724024427.752545-2-tdevries@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox