[gdb/testsuite] Fix timeout in gdb.threads/main-thread-exit-during-detach.exp

Message ID 20250318151455.8809-1-tdevries@suse.de
State Superseded
Headers
Series [gdb/testsuite] Fix timeout in gdb.threads/main-thread-exit-during-detach.exp |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Tom de Vries March 18, 2025, 3:14 p.m. UTC
  With a gdb 15.2 based package and test-case
gdb.threads/main-thread-exit-during-detach.exp, I ran into:
...
(gdb) attach 23068
Attaching to program: main-thread-exit-during-detach, process 23068
[New LWP 23080]
  ...
0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
(gdb) PASS: $exp: spawn_inferior=true: attach to the inferior
p 1 + 2
$1 = 3
(gdb)
Thread 2 "main-thread-exi" stopped.
0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
FAIL: $exp: spawn_inferior=true: p 1 + 2 (timeout)
...

I managed to reproduce this using two timing hacks.

First, we hack display_gdb_prompt to sleep half a second at the end:
...
       printf_unfiltered ("%s", actual_gdb_prompt.c_str ());
       gdb_flush (gdb_stdout);
     }
+  usleep (500 * 1000);
 }
...
to make sure expect has time to:
- parse the output of the attach command up until the prompt,
- issue "PASS: $exp: spawn_inferior=true: attach to the inferior", and
- issue "p 1 + 2"
before gdb issues the "Thread ... stopped." message.

Then we hack proc run_test to wait a while between issuing the print command
and parsing the output:
...
-	gdb_test "p 1 + 2" " = 3"
+	set cmd "p 1 + 2"
+	send_gdb "$cmd\n"
+	sleep 1
+	gdb_test "" " = 3" $cmd
...
to make sure that gdb has the time to issue the "Thread ... stopped." message
before the output is parsed.

Fix this by using -no-prompt-anchor.

Tested on x86_64-linux.

PR testsuite/32798
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32798
---
 gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


base-commit: 6eb9dab4c99725c1de4bccfeb99e766e7ee657a4
  

Comments

Simon Marchi March 18, 2025, 3:32 p.m. UTC | #1
On 3/18/25 11:14 AM, Tom de Vries wrote:
> With a gdb 15.2 based package and test-case
> gdb.threads/main-thread-exit-during-detach.exp, I ran into:
> ...
> (gdb) attach 23068
> Attaching to program: main-thread-exit-during-detach, process 23068
> [New LWP 23080]
>   ...
> 0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
> (gdb) PASS: $exp: spawn_inferior=true: attach to the inferior
> p 1 + 2
> $1 = 3
> (gdb)
> Thread 2 "main-thread-exi" stopped.
> 0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
> FAIL: $exp: spawn_inferior=true: p 1 + 2 (timeout)
> ...
> 
> I managed to reproduce this using two timing hacks.
> 
> First, we hack display_gdb_prompt to sleep half a second at the end:
> ...
>        printf_unfiltered ("%s", actual_gdb_prompt.c_str ());
>        gdb_flush (gdb_stdout);
>      }
> +  usleep (500 * 1000);
>  }
> ...
> to make sure expect has time to:
> - parse the output of the attach command up until the prompt,
> - issue "PASS: $exp: spawn_inferior=true: attach to the inferior", and
> - issue "p 1 + 2"
> before gdb issues the "Thread ... stopped." message.
> 
> Then we hack proc run_test to wait a while between issuing the print command
> and parsing the output:
> ...
> -	gdb_test "p 1 + 2" " = 3"
> +	set cmd "p 1 + 2"
> +	send_gdb "$cmd\n"
> +	sleep 1
> +	gdb_test "" " = 3" $cmd
> ...
> to make sure that gdb has the time to issue the "Thread ... stopped." message
> before the output is parsed.
> 
> Fix this by using -no-prompt-anchor.
> 
> Tested on x86_64-linux.
> 
> PR testsuite/32798
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32798
> ---
>  gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
> index 2a9320a6914..541718b6493 100644
> --- a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
> +++ b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
> @@ -79,7 +79,7 @@ proc run_test { spawn_inferior } {
>  	# is displayed.
>  	#
>  	# Send a simple command now just to resync the command prompt.
> -	gdb_test "p 1 + 2" " = 3"
> +	gdb_test -no-prompt-anchor "p 1 + 2" " = 3"

The reason for this gdb_test is explained by the comment just above:

	# Attaching to a multi-threaded application in non-stop mode
	# can result in thread stops being reported after the prompt
	# is displayed.
	#
	# Send a simple command now just to resync the command prompt.

If the thread stop notification is shown after the "p 1 + 2" command, as
shown in the commit message, then doesn't this defeat the purpose of
this gdb_test?  My understanding was that this gdb_test existed because
what follows couldn't deal with having the thread stop notification in
the expect buffer.  But then, it all passes with the -no-prompt-anchor
when the thread stop notification happens after the "1 + 2", it perhaps
shows that what comes after can cope with having the thread stop
notification in the expect buffer, and this gdb_test is just not needed?

Simon
  
Tom de Vries March 19, 2025, 9:29 a.m. UTC | #2
On 3/18/25 16:32, Simon Marchi wrote:
> On 3/18/25 11:14 AM, Tom de Vries wrote:
>> With a gdb 15.2 based package and test-case
>> gdb.threads/main-thread-exit-during-detach.exp, I ran into:
>> ...
>> (gdb) attach 23068
>> Attaching to program: main-thread-exit-during-detach, process 23068
>> [New LWP 23080]
>>    ...
>> 0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
>> (gdb) PASS: $exp: spawn_inferior=true: attach to the inferior
>> p 1 + 2
>> $1 = 3
>> (gdb)
>> Thread 2 "main-thread-exi" stopped.
>> 0x0000ffffb79aa178 in clock_nanosleep@@GLIBC_2.17 () from /lib64/libc.so.6
>> FAIL: $exp: spawn_inferior=true: p 1 + 2 (timeout)
>> ...
>>
>> I managed to reproduce this using two timing hacks.
>>
>> First, we hack display_gdb_prompt to sleep half a second at the end:
>> ...
>>         printf_unfiltered ("%s", actual_gdb_prompt.c_str ());
>>         gdb_flush (gdb_stdout);
>>       }
>> +  usleep (500 * 1000);
>>   }
>> ...
>> to make sure expect has time to:
>> - parse the output of the attach command up until the prompt,
>> - issue "PASS: $exp: spawn_inferior=true: attach to the inferior", and
>> - issue "p 1 + 2"
>> before gdb issues the "Thread ... stopped." message.
>>
>> Then we hack proc run_test to wait a while between issuing the print command
>> and parsing the output:
>> ...
>> -	gdb_test "p 1 + 2" " = 3"
>> +	set cmd "p 1 + 2"
>> +	send_gdb "$cmd\n"
>> +	sleep 1
>> +	gdb_test "" " = 3" $cmd
>> ...
>> to make sure that gdb has the time to issue the "Thread ... stopped." message
>> before the output is parsed.
>>
>> Fix this by using -no-prompt-anchor.
>>
>> Tested on x86_64-linux.
>>
>> PR testsuite/32798
>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32798
>> ---
>>   gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
>> index 2a9320a6914..541718b6493 100644
>> --- a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
>> +++ b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
>> @@ -79,7 +79,7 @@ proc run_test { spawn_inferior } {
>>   	# is displayed.
>>   	#
>>   	# Send a simple command now just to resync the command prompt.
>> -	gdb_test "p 1 + 2" " = 3"
>> +	gdb_test -no-prompt-anchor "p 1 + 2" " = 3"
> 
> The reason for this gdb_test is explained by the comment just above:
> 
> 	# Attaching to a multi-threaded application in non-stop mode
> 	# can result in thread stops being reported after the prompt
> 	# is displayed.
> 	#
> 	# Send a simple command now just to resync the command prompt.
> 
> If the thread stop notification is shown after the "p 1 + 2" command, as
> shown in the commit message, then doesn't this defeat the purpose of
> this gdb_test?  My understanding was that this gdb_test existed because
> what follows couldn't deal with having the thread stop notification in
> the expect buffer.  But then, it all passes with the -no-prompt-anchor
> when the thread stop notification happens after the "1 + 2", it perhaps
> shows that what comes after can cope with having the thread stop
> notification in the expect buffer, and this gdb_test is just not needed?

Hi Simon,

thanks for the review.

I suppose we could drop the print command, and add the -no-prompt-anchor 
to the following command instead to the same effect.

But I think there's another issue here: in order for the test setup to 
be complete, thread 2 needs to be stopped, and the assumption here seems 
to be that after the gdb_test "p 1 + 2", it is stopped.

I don't think we can assume that, and should check using "info thread".

I've submitted a v2 implementing this approach ( 
https://sourceware.org/pipermail/gdb-patches/2025-March/216464.html ).

Thanks,
- Tom
  

Patch

diff --git a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
index 2a9320a6914..541718b6493 100644
--- a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
+++ b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp
@@ -79,7 +79,7 @@  proc run_test { spawn_inferior } {
 	# is displayed.
 	#
 	# Send a simple command now just to resync the command prompt.
-	gdb_test "p 1 + 2" " = 3"
+	gdb_test -no-prompt-anchor "p 1 + 2" " = 3"
 
 	# Set thread 1 (the current thread) running again.
 	gdb_test "continue&"