Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] gdb, testsuite: use -no-prompt-anchor in step-over-thread-exit.exp
@ 2026-04-24 14:19 Tankut Baris Aktemur
  2026-04-27 20:44 ` Simon Marchi
  0 siblings, 1 reply; 3+ messages in thread
From: Tankut Baris Aktemur @ 2026-04-24 14:19 UTC (permalink / raw)
  To: gdb-patches

Running gdb.threads/step-over-thread-exit.exp with the
native-gdbserver boardfile sometimes fails with

  p $_thread == 2
  $1 = 1
  (gdb) [New Thread 2790806.2790823 (id 3)]

  Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
  85      SYSCALL (my_exit, __NR_exit)
  FAIL: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change (timeout)

The passing case is

  p $_thread == 2
  $1 = 1
  (gdb) PASS: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change
  Remote debugging from host 127.0.0.1, port 32932
  [New Thread 2784047.2784049 (id 3)]

  Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
  85      SYSCALL (my_exit, __NR_exit)

Fix the problem by using -no-prompt-anchor.  Since this is non-stop
mode, it should be ok to use the flag.
---
 gdb/testsuite/gdb.threads/step-over-thread-exit.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp
index f398538058d..1dd1191afdc 100644
--- a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp
+++ b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp
@@ -185,7 +185,7 @@ proc test {step_over_mode non-stop target-non-stop schedlock cmd ns_stop_all} {
 			pass $gdb_test_name
 		    }
 		}
-		gdb_test "p \$_thread == $thread" "= 1" \
+		gdb_test -no-prompt-anchor "p \$_thread == $thread" "= 1" \
 		    "selected thread didn't change"
 	    }
 	} else {
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] gdb, testsuite: use -no-prompt-anchor in step-over-thread-exit.exp
  2026-04-24 14:19 [PATCH] gdb, testsuite: use -no-prompt-anchor in step-over-thread-exit.exp Tankut Baris Aktemur
@ 2026-04-27 20:44 ` Simon Marchi
  2026-05-06 20:31   ` Simon Marchi
  0 siblings, 1 reply; 3+ messages in thread
From: Simon Marchi @ 2026-04-27 20:44 UTC (permalink / raw)
  To: Tankut Baris Aktemur, gdb-patches

On 4/24/26 10:19 AM, Tankut Baris Aktemur wrote:
> Running gdb.threads/step-over-thread-exit.exp with the
> native-gdbserver boardfile sometimes fails with
> 
>   p $_thread == 2
>   $1 = 1
>   (gdb) [New Thread 2790806.2790823 (id 3)]
> 
>   Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
>   85      SYSCALL (my_exit, __NR_exit)
>   FAIL: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change (timeout)
> 
> The passing case is
> 
>   p $_thread == 2
>   $1 = 1
>   (gdb) PASS: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change
>   Remote debugging from host 127.0.0.1, port 32932
>   [New Thread 2784047.2784049 (id 3)]
> 
>   Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
>   85      SYSCALL (my_exit, __NR_exit)
> 
> Fix the problem by using -no-prompt-anchor.  Since this is non-stop
> mode, it should be ok to use the flag.

I'm trying to understand more deeply what happens and try to reproduce
it reliable.

First of all, I was confused by the the "Remote debugging from host"
message, but that is from gdbserver, not GDB, so it doesn't come into
play in the "gdb_test" matching, ok.

What happens is that after the "next" that produces "Command aborted,
thread exited", another thread (thread 3) is created and hits the
syscall breakpoint.  And since this is non-stop, it can be shown at
anytime.

But why would that be specific to native-gdbserver?  We have:

	if {$cmd != "continue" || $step_over_mode == "none"} {
	    set n_threads 1
	} else {
	    set n_threads 100
	}

	gdb_test_no_output "set args $n_threads"

n_threads should be 1, the program should not spawn a another thread
that hits the breakpoint, why does it?  $cmd is "next" and
$step_over_mode is "inline".  Perhaps the args don't reach the test
program correctly when ran with native-gdbserver?

I changed the test program to exit with an error when argc != 2 (the
test should always pass an explicit number of threads, so there is no
point in having a default value of 100). And indeed, this shows that
n_threads doesn't reach the test program.  "set args" doesn't work with
native-gdbserver.

Setting n_threads to 1 is meant to avoid this kind of problem:

	# With step/next, GDB aborts the execution command with
	# "Command aborted, thread exited." when the stepping thread
	# exits.  If we let the main spawn another thread as soon as
	# the first exits, it would be possible for that new thread to
	# hit the exit syscall insn breakpoint quickly enough that it
	# would be reported to be user before the first thread exit
	# would be, which would confuse testing.  To avoid that, we
	# only spawn one thread, too.

What we see here seems to be a variation of that.

See this commit (especially the "Fixes a race" part of the commit
message):

https://gitlab.com/gnutools/binutils-gdb/-/commit/4ea7412e53616ecc29d61a95ff8afc284ed9d240

I guess that this n_threads fix was broken with native-gdbserver since
then?

I propose to do the following changes:

 - Pass `n_threads` by poking the variable from GDB once the program was
   started and is stopped at main.  Alternatively, it would be nice to
   change "runto" and friends to be able to pass inferior args, that
   would be nicer than poking variables manually, but that is a bigger
   project.  Today, we can use gdb_run_cmd to pass args to the test
   program, but it would be nice to be able to use the higher level
   runto/runto_main for this.

 - Use `-wrap` in the gdb_test_multiple "command aborts when thread
   exits", or better yet turn it into a simple gdb_test.  Since there
   shouldn't be another thread spawned after the one that exits during
   the step, we shouldn't see anything after the prompt.

I just saw that the test relies on a "sleep (3)" in the main thread,
just before the process exits, which isn't great.  I suppose this could
(unlikely) happen:

  - step command completes, prints the "Command aborted, thread exited"
    message plus prompt
  - main thread goes into sleep (3)
  - expect somehow doesn't get scheduled for > 3 seconds
  - main thread exits
  - gdb prints "inferior exited blah blah blah"
  - expect wakes up and reads the GDB output, test fails because there
    is output after the prompt

The same problem could also mess up the "p $thread == ..." test, exactly
how you described in the commit message.  I think we should remove that
sleep and replace it with a global variable "allowed to exit" flag that
GDB sets to let the main thread exit (but as another patch).  It might
also make the test run faster in the cases where it reaches exit.

Simon

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] gdb, testsuite: use -no-prompt-anchor in step-over-thread-exit.exp
  2026-04-27 20:44 ` Simon Marchi
@ 2026-05-06 20:31   ` Simon Marchi
  0 siblings, 0 replies; 3+ messages in thread
From: Simon Marchi @ 2026-05-06 20:31 UTC (permalink / raw)
  To: gdb-patches, Tankut.Aktemur



On 2026-04-27 16:44, Simon Marchi wrote:
> On 4/24/26 10:19 AM, Tankut Baris Aktemur wrote:
>> Running gdb.threads/step-over-thread-exit.exp with the
>> native-gdbserver boardfile sometimes fails with
>>
>>   p $_thread == 2
>>   $1 = 1
>>   (gdb) [New Thread 2790806.2790823 (id 3)]
>>
>>   Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
>>   85      SYSCALL (my_exit, __NR_exit)
>>   FAIL: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change (timeout)
>>
>> The passing case is
>>
>>   p $_thread == 2
>>   $1 = 1
>>   (gdb) PASS: gdb.threads/step-over-thread-exit.exp: step_over_mode=inline: non-stop=on: target-non-stop=on: schedlock=off: cmd=next: ns_stop_all=0: selected thread didn't change
>>   Remote debugging from host 127.0.0.1, port 32932
>>   [New Thread 2784047.2784049 (id 3)]
>>
>>   Thread 3 "step-over-threa" hit Breakpoint 2, 0x00005555555552ab in my_exit_syscall () at /.../testsuite/lib/my-syscalls.S:85
>>   85      SYSCALL (my_exit, __NR_exit)
>>
>> Fix the problem by using -no-prompt-anchor.  Since this is non-stop
>> mode, it should be ok to use the flag.
> 
> I'm trying to understand more deeply what happens and try to reproduce
> it reliable.
> 
> First of all, I was confused by the the "Remote debugging from host"
> message, but that is from gdbserver, not GDB, so it doesn't come into
> play in the "gdb_test" matching, ok.
> 
> What happens is that after the "next" that produces "Command aborted,
> thread exited", another thread (thread 3) is created and hits the
> syscall breakpoint.  And since this is non-stop, it can be shown at
> anytime.
> 
> But why would that be specific to native-gdbserver?  We have:
> 
> 	if {$cmd != "continue" || $step_over_mode == "none"} {
> 	    set n_threads 1
> 	} else {
> 	    set n_threads 100
> 	}
> 
> 	gdb_test_no_output "set args $n_threads"
> 
> n_threads should be 1, the program should not spawn a another thread
> that hits the breakpoint, why does it?  $cmd is "next" and
> $step_over_mode is "inline".  Perhaps the args don't reach the test
> program correctly when ran with native-gdbserver?
> 
> I changed the test program to exit with an error when argc != 2 (the
> test should always pass an explicit number of threads, so there is no
> point in having a default value of 100). And indeed, this shows that
> n_threads doesn't reach the test program.  "set args" doesn't work with
> native-gdbserver.
> 
> Setting n_threads to 1 is meant to avoid this kind of problem:
> 
> 	# With step/next, GDB aborts the execution command with
> 	# "Command aborted, thread exited." when the stepping thread
> 	# exits.  If we let the main spawn another thread as soon as
> 	# the first exits, it would be possible for that new thread to
> 	# hit the exit syscall insn breakpoint quickly enough that it
> 	# would be reported to be user before the first thread exit
> 	# would be, which would confuse testing.  To avoid that, we
> 	# only spawn one thread, too.
> 
> What we see here seems to be a variation of that.
> 
> See this commit (especially the "Fixes a race" part of the commit
> message):
> 
> https://gitlab.com/gnutools/binutils-gdb/-/commit/4ea7412e53616ecc29d61a95ff8afc284ed9d240
> 
> I guess that this n_threads fix was broken with native-gdbserver since
> then?
> 
> I propose to do the following changes:
> 
>  - Pass `n_threads` by poking the variable from GDB once the program was
>    started and is stopped at main.  Alternatively, it would be nice to
>    change "runto" and friends to be able to pass inferior args, that
>    would be nicer than poking variables manually, but that is a bigger
>    project.  Today, we can use gdb_run_cmd to pass args to the test
>    program, but it would be nice to be able to use the higher level
>    runto/runto_main for this.
> 
>  - Use `-wrap` in the gdb_test_multiple "command aborts when thread
>    exits", or better yet turn it into a simple gdb_test.  Since there
>    shouldn't be another thread spawned after the one that exits during
>    the step, we shouldn't see anything after the prompt.
> 
> I just saw that the test relies on a "sleep (3)" in the main thread,
> just before the process exits, which isn't great.  I suppose this could
> (unlikely) happen:
> 
>   - step command completes, prints the "Command aborted, thread exited"
>     message plus prompt
>   - main thread goes into sleep (3)
>   - expect somehow doesn't get scheduled for > 3 seconds
>   - main thread exits
>   - gdb prints "inferior exited blah blah blah"
>   - expect wakes up and reads the GDB output, test fails because there
>     is output after the prompt
> 
> The same problem could also mess up the "p $thread == ..." test, exactly
> how you described in the commit message.  I think we should remove that
> sleep and replace it with a global variable "allowed to exit" flag that
> GDB sets to let the main thread exit (but as another patch).  It might
> also make the test run faster in the cases where it reaches exit.

I sent a series that teaches the testsuite to properly pass
arguments to inferior programs (even with the native-gdbserver board),
and used it to fix the problem above.

https://inbox.sourceware.org/gdb-patches/20260506202804.1681886-1-simon.marchi@polymtl.ca/T/#m9a8716af21f9f31b3a5cf1abcdadb522d6c45e9f

Simon

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-06 20:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-24 14:19 [PATCH] gdb, testsuite: use -no-prompt-anchor in step-over-thread-exit.exp Tankut Baris Aktemur
2026-04-27 20:44 ` Simon Marchi
2026-05-06 20:31   ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox