Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 04/16] Fix gdb.multi/multi-term-settings.exp race
Date: Mon, 14 Jun 2021 22:23:58 +0100	[thread overview]
Message-ID: <20210614212410.1612666-5-pedro@palves.net> (raw)
In-Reply-To: <20210614212410.1612666-1-pedro@palves.net>

The gdb.multi/multi-term-settings.exp testcase sometimes fails like so:

 Running /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.multi/multi-term-settings.exp ...
 FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c (SIGINT)

It's easier to reproduce if you stress the machine at the same time, like e.g.:

  $ stress -c 24

Looking at gdb.log, we see:

 (gdb) attach 60422
 Attaching to program: build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings, process 60422
 [New Thread 60422.60422]
 Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
 Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.31.so...
 Reading symbols from /lib64/ld-linux-x86-64.so.2...
 (No debugging symbols found in /lib64/ld-linux-x86-64.so.2)
 0x00007f2fc2485334 in __GI___clock_nanosleep (clock_id=<optimized out>, clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7ffe23126940, rem=rem@entry=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
 78	../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory.
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: inf2: attach
 set schedule-multiple on
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: set schedule-multiple on
 info inferiors
   Num  Description       Connection                         Executable
   1    process 60404     1 (extended-remote localhost:2349) build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings
 * 2    process 60422     1 (extended-remote localhost:2349) build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: info inferiors
 pid=60422, count=46
 pid=60422, count=47
 pid=60422, count=48
 pid=60422, count=49
 pid=60422, count=50
 pid=60422, count=51
 pid=60422, count=52
 pid=60422, count=53
 pid=60422, count=54
 pid=60422, count=55
 pid=60422, count=56
 pid=60422, count=57
 pid=60422, count=58
 pid=60422, count=59
 pid=60422, count=60
 pid=60422, count=61
 pid=60422, count=62
 pid=60422, count=63
 pid=60422, count=64
 pid=60422, count=65
 pid=60422, count=66
 pid=60422, count=67
 pid=60422, count=68
 pid=60422, count=69
 pid=60404, count=54
 pid=60404, count=55
 pid=60404, count=56
 pid=60404, count=57
 pid=60404, count=58
 PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: continue
 Quit
 (gdb) FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c (SIGINT)

If you look at the testcase's sources, you'll see that the intention
is to resumes the program with "continue", wait to see a few of those
"pid=..., count=..." lines, and then interrupt the program with
Ctrl-C.  But somehow, that resulted in GDB printing "Quit", instead of
the Ctrl-C stopping the program with SIGINT.

Here's what is happening:

 #1 - those "pid=..., count=..." lines we see above weren't actually
      output by the inferior after it has been continued (see #1).
      Note that "inf1_how" and "inf2_how" are "attach".  What happened
      is that those "pid=..., count=..." lines were output by the
      inferiors _before_ they were attached to.  We see them at that
      point instead of earlier, because that's where the testcase
      reads from the inferiors' spawn_ids.

 #2 - The testcase mistakenly thinks those "pid=..., count=..." lines
      happened after the continue was processed by GDB, meaning it has
      waited enough, and so sends the Ctrl-C.  GDB hasn't yet passed
      the terminal to the inferior, so the Ctrl-C results in that
      Quit.

The fix here is twofold:

 #1 - flush inferior output right after attaching

 #2 - consume the "Continuing" printed by "continue", indicating the
      inferior has the terminal.  This is the same as done throughout
      the testsuite to handle this exact problem of sending Ctrl-C too
      soon.

gdb/testsuite/ChangeLog:
yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

	* gdb.multi/multi-term-settings.exp (create_inferior): Flush
	inferior output.
	(coretest): Use $gdb_test_name.  After issuing "continue", wait
	for "Continuing".

Change-Id: Iba7671dfe1eee6b98d29cfdb05a1b9aa2f9defb9
---
 .../gdb.multi/multi-term-settings.exp         | 40 ++++++++++++++++---
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/gdb/testsuite/gdb.multi/multi-term-settings.exp b/gdb/testsuite/gdb.multi/multi-term-settings.exp
index 20ec03d94b3..dcc6f2ece0f 100644
--- a/gdb/testsuite/gdb.multi/multi-term-settings.exp
+++ b/gdb/testsuite/gdb.multi/multi-term-settings.exp
@@ -95,6 +95,22 @@ proc create_inferior {which_inf inf_how} {
 	if {[gdb_test "attach $testpid" \
 		 "Attaching to program: .*, process $testpid.*(in|at).*" \
 		 "attach"] == 0} {
+
+	    # The program is now stopped, but if testing against
+	    # gdbserver, then the inferior's output emmitted before it
+	    # stopped isn't flushed unless we explicitly do so,
+	    # because it is on a different spawn_id.  Do it now, to
+	    # avoid confusing tests further below.
+	    gdb_test_multiple "" "flush inferior output" {
+		-timeout 1
+		-i $test_spawn_id -re "pid=" {
+		    exp_continue
+		}
+		timeout {
+		    pass $gdb_test_name
+		}
+	    }
+
 	    return $test_spawn_id
 	}
     } else {
@@ -179,9 +195,9 @@ proc coretest {inf1_how inf2_how} {
 	uplevel 1 {
 	    if {$count1 >= 3 && $count2 >= 3} {
 		if $expect_ttou {
-		    fail "$test (expected SIGTTOU)"
+		    fail "$gdb_test_name (expected SIGTTOU)"
 		} else {
-		    pass $test
+		    pass $gdb_test_name
 		}
 	    } else {
 		exp_continue
@@ -195,8 +211,20 @@ proc coretest {inf1_how inf2_how} {
     set count1 0
     set count2 0
 
-    set test "continue"
-    gdb_test_multiple $test $test {
+    # We're going to interrupt with Ctrl-C.  For this to work we must
+    # be sure to consume the "Continuing." message first, or GDB may
+    # still own the terminal.  Also, note that in the attach case, we
+    # flushed inferior output right after attaching, so that we're
+    # sure that the "pid=" lines we see are emitted by the inferior
+    # after it is continued, instead of having been emitted before it
+    # was attached to.
+    gdb_test_multiple "continue" "continue, hand over terminal" {
+	-re "Continuing" {
+	    pass $gdb_test_name
+	}
+    }
+
+    gdb_test_multiple "" "continue" {
 	-i $infs_spawn_ids -re "pid=$pid1, count=" {
 	    incr count1
 	    pass_or_exp_continue
@@ -207,9 +235,9 @@ proc coretest {inf1_how inf2_how} {
 	}
 	-i $gdb_spawn_id -re "received signal SIGTTOU.*$gdb_prompt " {
 	    if $expect_ttou {
-		pass "$test (expected SIGTTOU)"
+		pass "$gdb_test_name (expected SIGTTOU)"
 	    } else {
-		fail "$test (SIGTTOU)"
+		fail "$gdb_test_name (SIGTTOU)"
 	    }
 	}
     }
-- 
2.26.2


  parent reply	other threads:[~2021-06-14 21:25 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-14 21:23 [PATCH v2 00/16] Interrupting programs that block/ignore SIGINT Pedro Alves
2021-06-14 21:23 ` [PATCH v2 01/16] Test interrupting programs that block SIGINT [gdb/9425, gdb/14559] Pedro Alves
2021-06-14 21:23 ` [PATCH v2 02/16] prefork_hook: Remove 'args' parameter Pedro Alves
2021-06-14 21:23 ` [PATCH v2 03/16] Make gdb.base/long-inferior-output.exp fail fast Pedro Alves
2021-06-14 21:23 ` Pedro Alves [this message]
2021-06-14 21:23 ` [PATCH v2 05/16] Don't check parent pid in gdb.threads/{ia64-sigill, siginfo-threads, watchthreads-reorder}.c Pedro Alves
2021-06-14 21:24 ` [PATCH v2 06/16] Special-case "set inferior-tty /dev/tty" Pedro Alves
2021-06-14 21:24 ` [PATCH v2 07/16] Make inferior/GDB share terminal in tests expecting output after detach Pedro Alves
2021-06-14 21:24 ` [PATCH v2 08/16] Make inferior/GDB share terminal in tests that exercise GDB/inferior reading same input Pedro Alves
2021-06-14 21:24 ` [PATCH v2 09/16] gdb.mi/mi-logging.exp, don't send input to GDB while the inferior is running Pedro Alves
2021-06-14 21:24 ` [PATCH v2 10/16] target_terminal::ours_for_output before printing signal received Pedro Alves
2021-06-14 21:24 ` [PATCH v2 11/16] Move scoped_ignore_sigttou to gdbsupport/ Pedro Alves
2021-06-17 21:49   ` Pedro Alves
2021-06-14 21:24 ` [PATCH v2 12/16] Always put inferiors in their own terminal/session [gdb/9425, gdb/14559] Pedro Alves
2021-06-14 21:24 ` [PATCH v2 13/16] exists_non_stop_target: Avoid flushing frames Pedro Alves
2021-06-14 21:24 ` [PATCH v2 14/16] convert previous_inferior_ptid to strong reference to thread_info Pedro Alves
2021-06-14 21:24 ` [PATCH v2 15/16] GNU/Linux: Interrupt/Ctrl-C with SIGSTOP instead of SIGINT [PR gdb/9425, PR gdb/14559] Pedro Alves
2021-07-08 23:05   ` Maciej W. Rozycki
2021-07-13 15:26     ` Pedro Alves
2021-06-14 21:24 ` [PATCH v2 16/16] Document pseudo-terminal and interrupting changes Pedro Alves
2021-06-15 12:56   ` Eli Zaretskii via Gdb-patches
2021-06-16  9:31     ` Pedro Alves
2021-06-16 12:29       ` Eli Zaretskii via Gdb-patches
2021-06-16 10:15     ` Pedro Alves
2021-06-16 12:15       ` Eli Zaretskii via Gdb-patches
2021-06-16 12:26         ` Pedro Alves
2021-06-16 13:05           ` Eli Zaretskii via Gdb-patches
2021-06-15 12:34 ` [PATCH v2 00/16] Interrupting programs that block/ignore SIGINT Eli Zaretskii via Gdb-patches
2021-06-16 11:27   ` Pedro Alves
2021-06-16 12:45     ` Eli Zaretskii via Gdb-patches
2021-06-18 10:12 ` Andrew Burgess
2021-06-24 18:12 ` Konstantin Kharlamov via Gdb-patches
2021-06-24 18:55   ` Pedro Alves
2021-06-29  1:15     ` Eldar Abusalimov via Gdb-patches

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=20210614212410.1612666-5-pedro@palves.net \
    --to=pedro@palves.net \
    --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