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 1/2] [gdb/testsuite] Fix race in gdb.threads/leader-exit.exp
Date: Thu, 23 Jul 2026 13:40:41 +0200	[thread overview]
Message-ID: <20260723114042.703464-2-tdevries@suse.de> (raw)
In-Reply-To: <20260723114042.703464-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   | 22 +++++++++++++++++++++
 gdb/testsuite/gdb.threads/non-ldr-exc-2.c   |  5 +++++
 gdb/testsuite/gdb.threads/non-ldr-exc-2.exp | 22 +++++++++++++++++++++
 4 files changed, 53 insertions(+)

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..22f27d2d6e8 100644
--- a/gdb/testsuite/gdb.threads/leader-exit.exp
+++ b/gdb/testsuite/gdb.threads/leader-exit.exp
@@ -30,6 +30,28 @@ if {![runto_main]} {
     return
 }
 
+# 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 [gdb_get_line_number "break-here"]
 gdb_continue_to_breakpoint "break-here" ".* break-here .*"
 
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..dfc34f42afe 100644
--- a/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp
+++ b/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp
@@ -37,6 +37,28 @@ proc do_test { lock_sched nonstop } {
 	return -1
     }
 
+    # 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 [gdb_get_line_number "break-here"]
     gdb_continue_to_breakpoint "break-here" ".* break-here .*"
 
-- 
2.51.0


  reply	other threads:[~2026-07-23 11:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 11:40 [PATCH 0/2] [gdb/testsuite] Two gdb.threads patches Tom de Vries
2026-07-23 11:40 ` Tom de Vries [this message]
2026-07-24 17:49   ` [PATCH 1/2] [gdb/testsuite] Fix race in gdb.threads/leader-exit.exp Keith Seitz
2026-07-25  7:03     ` Tom de Vries
2026-07-23 11:40 ` [PATCH 2/2] [gdb/testsuite] Fix timeout in gdb.threads/vfork-multi-inferior.exp Tom de Vries
2026-07-24 17:52   ` Keith Seitz

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=20260723114042.703464-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