[gdb/testsuite] Fix timeout in gdb.base/bg-execution-repeat.exp

Message ID 20240524145649.28355-1-tdevries@suse.de
State New
Headers
Series [gdb/testsuite] Fix timeout in gdb.base/bg-execution-repeat.exp |

Checks

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

Commit Message

Tom de Vries May 24, 2024, 2:56 p.m. UTC
  I ran into the following test failure with test-case
gdb.base/bg-execution-repeat.exp:
...
(gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: repeat bg command
^M
Breakpoint 2, foo () at bg-execution-repeat.c:23^M
23        return 0; /* set break here */^M
print 1^M
$1 = 1^M
(gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: input still accepted
FAIL: gdb.base/bg-execution-repeat.exp: c&: breakpoint hit 2 (timeout)
...

The failure can be easily reproduced by adding a sleep 5 here:
...
+    sleep 5
     gdb_test "print 1" " = 1" "input still accepted"
...

There's a race in the test-case, between:
- the command handled in the foreground: the "print 1" command, and
- the command handled in the background: the continue command.

The current way of dealing with this is by putting the inferior to sleep for 5
seconds:
...
  foo ();
  sleep (5);
  foo ();
...
with the aim that the "print 1" command will win the race.

This method is both slow and unreliable.

Fix this by making the inferior wait just long enough for the "print 1"
command to win the race.

This reduces running time from ~11s to ~1s.

Tested on aarch64-linux.

PR testsuite/31794
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31794
---
 gdb/testsuite/gdb.base/bg-execution-repeat.c   | 16 +++++++++++++++-
 gdb/testsuite/gdb.base/bg-execution-repeat.exp |  3 +++
 2 files changed, 18 insertions(+), 1 deletion(-)


base-commit: 2597ca3417d9adb0adda135c90ab86c4ea675139
  

Comments

Tom de Vries June 13, 2024, 7:54 a.m. UTC | #1
On 5/24/24 16:56, Tom de Vries wrote:
> I ran into the following test failure with test-case
> gdb.base/bg-execution-repeat.exp:
> ...
> (gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: repeat bg command
> ^M
> Breakpoint 2, foo () at bg-execution-repeat.c:23^M
> 23        return 0; /* set break here */^M
> print 1^M
> $1 = 1^M
> (gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: input still accepted
> FAIL: gdb.base/bg-execution-repeat.exp: c&: breakpoint hit 2 (timeout)
> ...
> 
> The failure can be easily reproduced by adding a sleep 5 here:
> ...
> +    sleep 5
>       gdb_test "print 1" " = 1" "input still accepted"
> ...
> 
> There's a race in the test-case, between:
> - the command handled in the foreground: the "print 1" command, and
> - the command handled in the background: the continue command.
> 
> The current way of dealing with this is by putting the inferior to sleep for 5
> seconds:
> ...
>    foo ();
>    sleep (5);
>    foo ();
> ...
> with the aim that the "print 1" command will win the race.
> 
> This method is both slow and unreliable.
> 
> Fix this by making the inferior wait just long enough for the "print 1"
> command to win the race.
> 
> This reduces running time from ~11s to ~1s.
> 
> Tested on aarch64-linux.
> 

During re-testing on x86_64-linux, I realized that with target board 
native-gdbserver I run into:
...
(gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: input still accepted
set var do_wait=0^M
Cannot execute this command while the target is running.^M
Use the "interrupt" command to stop the target^M
and then try again.^M
(gdb) PASS: gdb.base/bg-execution-repeat.exp: c&: set var do_wait=0
FAIL: gdb.base/bg-execution-repeat.exp: c&: breakpoint hit 2 (timeout)
...

I could remodel the test-case in the style of 
gdb.base/access-mem-running.exp, but haven't made up my mind about it yet.

Thanks,
- Tom

> PR testsuite/31794
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31794
> ---
>   gdb/testsuite/gdb.base/bg-execution-repeat.c   | 16 +++++++++++++++-
>   gdb/testsuite/gdb.base/bg-execution-repeat.exp |  3 +++
>   2 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.c b/gdb/testsuite/gdb.base/bg-execution-repeat.c
> index 2caa7d442f6..c92d34ed9f9 100644
> --- a/gdb/testsuite/gdb.base/bg-execution-repeat.c
> +++ b/gdb/testsuite/gdb.base/bg-execution-repeat.c
> @@ -23,11 +23,25 @@ foo (void)
>     return 0; /* set break here */
>   }
>   
> +static volatile int do_wait;
> +
> +static void
> +wait (void)
> +{
> +  while (do_wait)
> +    usleep (10 * 1000);
> +}
> +
>   int
>   main (void)
>   {
>     foo ();
> -  sleep (5);
> +
> +  do_wait = 1;
> +  wait ();
> +  /* do_wait set to 0 externally.  */
> +
>     foo ();
> +
>     return 0;
>   }
> diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.exp b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
> index a4cc7daa702..3497ef2d47d 100644
> --- a/gdb/testsuite/gdb.base/bg-execution-repeat.exp
> +++ b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
> @@ -68,6 +68,9 @@ proc test {continue_cmd} {
>       # stopped.
>       gdb_test "print 1" " = 1" "input still accepted"
>   
> +    # Allow the breakpoint to trigger.
> +    gdb_test -no-prompt-anchor "set var do_wait=0"
> +
>       # Make sure we see a stop after the print, and not before.  Don't
>       # expect a prompt, as we had resumed the inferior in the background.
>       set test "breakpoint hit 2"
> 
> base-commit: 2597ca3417d9adb0adda135c90ab86c4ea675139
  

Patch

diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.c b/gdb/testsuite/gdb.base/bg-execution-repeat.c
index 2caa7d442f6..c92d34ed9f9 100644
--- a/gdb/testsuite/gdb.base/bg-execution-repeat.c
+++ b/gdb/testsuite/gdb.base/bg-execution-repeat.c
@@ -23,11 +23,25 @@  foo (void)
   return 0; /* set break here */
 }
 
+static volatile int do_wait;
+
+static void
+wait (void)
+{
+  while (do_wait)
+    usleep (10 * 1000);
+}
+
 int
 main (void)
 {
   foo ();
-  sleep (5);
+
+  do_wait = 1;
+  wait ();
+  /* do_wait set to 0 externally.  */
+
   foo ();
+
   return 0;
 }
diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.exp b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
index a4cc7daa702..3497ef2d47d 100644
--- a/gdb/testsuite/gdb.base/bg-execution-repeat.exp
+++ b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
@@ -68,6 +68,9 @@  proc test {continue_cmd} {
     # stopped.
     gdb_test "print 1" " = 1" "input still accepted"
 
+    # Allow the breakpoint to trigger.
+    gdb_test -no-prompt-anchor "set var do_wait=0"
+
     # Make sure we see a stop after the print, and not before.  Don't
     # expect a prompt, as we had resumed the inferior in the background.
     set test "breakpoint hit 2"