This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/6] testsuite: Introduce $inferior_spawn_id


Some important tests, like gdb.base/interrupt.exp end up skipped
against gdbserver, because they depend on inferior I/O, which
gdbserver doesn't do.

This patch adds a mechanism that makes it possible to make them work.
It adds a new "inferior_spawn_id" global that is the spawn ID used for
I/O interaction with the inferior.  By default, for native targets, or
remote targets that can do I/O through GDB (semi-hosting) this will be
the same as the gdb/host spawn ID.  Otherwise, the board may set this
to some other spawn ID.  When debugging with GDBserver, this will be
set to GDBserver's spawn ID.

Then tests can use send_inferior instead of send_gdb to send input to
the inferior, and use expect's "-i" switch to select which spawn ID to
use for matching input/output.  That is, something like this will now
work:

  send_inferior "echo me\n"
  gdb_test_multiple "continue" "test msg" {
    -i "$inferior_spawn_id" -re "echo me\r\necho\r\n" {
      ...
    }
  }

Or even:

  gdb_test_multiple "continue" "test msg" {
    -i "$inferior_spawn_id" -re "hello world" {
      ...
    }
    -i "$gdb_spawn_id" -re "error.*$gdb_prompt $" {
      ...
    }
  }

Of course, by default, gdb_test_multiple still matches with
$gdb_spawn_id.

gdb/testsuite/ChangeLog:
2015-02-23  Pedro Alves  <palves@redhat.com>

	* lib/gdb.exp (inferior_spawn_id): New global.
	(gdb_test_multiple): Handle "-i".  Reset the spawn id to GDB's
	spawn id after processing the user code.
	(default_gdb_start): Set inferior_spawn_id.
	(send_inferior): New procedure.
	* lib/gdbserver-support.exp (gdbserver_start): Set
	inferior_spawn_id.
	(close_gdbserver, gdb_exit): Unset inferior_spawn_id.
---
 gdb/testsuite/lib/gdb.exp               | 51 +++++++++++++++++++++++++++++++--
 gdb/testsuite/lib/gdbserver-support.exp | 11 +++++--
 2 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 3e8e574..e4722d2 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -31,6 +31,14 @@ load_lib gdb-utils.exp
 
 global GDB
 
+# The spawn ID used for I/O interaction with the inferior.  For native
+# targets, or remote targets that can do I/O through GDB
+# (semi-hosting) this will be the same as the host/GDB's spawn ID.
+# Otherwise, the board may set this to some other spawn ID.  E.g.,
+# when debugging with GDBserver, this is set to GDBserver's spawn ID,
+# so input/output is done on gdbserver's tty.
+global inferior_spawn_id
+
 if [info exists TOOL_EXECUTABLE] {
     set GDB $TOOL_EXECUTABLE
 }
@@ -646,13 +654,31 @@ proc gdb_internal_error_resync {} {
 #    }
 # }
 #
+# Like with "expect", you can also specify the spawn id to match with
+# -i "$id".  Interesting spawn ids are $inferior_spawn_id and
+# $gdb_spawn_id.  The former matches inferior I/O, while the latter
+# matches GDB I/O.  E.g.:
+#
+# send_inferior "hello\n"
+# gdb_test_multiple "continue" "test echo" {
+#    -i "$inferior_spawn_id" -re "^hello\r\nhello\r\n$" {
+#        pass "got echo"
+#    }
+#    -i "$gdb_spawn_id" -re "Breakpoint.*$gdb_prompt $" {
+#        fail "hit breakpoint"
+#    }
+# }
+#
 # The standard patterns, such as "Inferior exited..." and "A problem
-# ...", all being implicitly appended to that list.
+# ...", all being implicitly appended to that list.  These are always
+# expected from $gdb_spawn_id.  IOW, callers do not need to worry
+# about resetting "-i" back to $gdb_spawn_id explicitly.
 #
 proc gdb_test_multiple { command message user_code } {
     global verbose use_gdb_stub
     global gdb_prompt pagination_prompt
     global GDB
+    global gdb_spawn_id
     global inferior_exited_re
     upvar timeout timeout
     upvar expect_out expect_out
@@ -713,7 +739,7 @@ proc gdb_test_multiple { command message user_code } {
 	    lappend processed_code $item
 	    continue
 	}
-	if { $item == "-timeout" } {
+	if { $item == "-timeout" || $item == "-i" } {
 	    set expecting_arg 1
 	    lappend processed_code $item
 	    continue
@@ -809,6 +835,9 @@ proc gdb_test_multiple { command message user_code } {
     }
     append code $processed_code
     append code {
+	# Reset the spawn id, in case the processed code used -i.
+	-i "$gdb_spawn_id"
+
 	-re "Ending remote debugging.*$gdb_prompt $" {
 	    if ![isnative] then {
 		warning "Can`t communicate to remote target."
@@ -1454,6 +1483,7 @@ proc default_gdb_spawn { } {
 proc default_gdb_start { } {
     global gdb_prompt pagination_prompt
     global gdb_spawn_id
+    global inferior_spawn_id
 
     if [info exists gdb_spawn_id] {
 	return 0
@@ -1464,6 +1494,11 @@ proc default_gdb_start { } {
 	return $res
     }
 
+    # Default to assuming inferior I/O is done on GDB's terminal.
+    if {![info exists inferior_spawn_id]} {
+	set inferior_spawn_id $gdb_spawn_id
+    }
+
     # When running over NFS, particularly if running many simultaneous
     # tests on different hosts all using the same server, things can
     # get really slow.  Give gdb at least 3 minutes to start up.
@@ -3195,6 +3230,18 @@ proc send_gdb { string } {
     return [remote_send host "$string"]
 }
 
+# Send STRING to the inferior's terminal.
+
+proc send_inferior { string } {
+    global inferior_spawn_id
+
+    if {[catch "send -i $inferior_spawn_id -- \$string" errorInfo]} {
+	return "$errorInfo"
+    } else {
+	return ""
+    }
+}
+
 #
 #
 
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index f19b796..53843b8 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -273,6 +273,11 @@ proc gdbserver_start { options arguments } {
 	global server_spawn_id
 	set server_spawn_id [remote_spawn target $gdbserver_command]
 
+	# GDBserver doesn't do inferior I/O through GDB.  But we can
+	# talk to the program using GDBserver's tty instead.
+	global inferior_spawn_id
+	set inferior_spawn_id $server_spawn_id
+
 	# Wait for the server to open its TCP socket, so that GDB can connect.
 	expect {
 	    -i $server_spawn_id
@@ -319,7 +324,7 @@ proc gdbserver_spawn { child_args } {
 # Close the GDBserver connection.
 
 proc close_gdbserver {} {
-    global server_spawn_id
+    global server_spawn_id inferior_spawn_id
 
     # We can't just call close, because if gdbserver is local then that means
     # that it will get a SIGHUP.  Doing it this way could also allow us to
@@ -335,6 +340,7 @@ proc close_gdbserver {} {
     catch "close -i $server_spawn_id"
     catch "wait -i $server_spawn_id"
     unset server_spawn_id
+    unset inferior_spawn_id
 }
 
 # Hook into GDB exit, and close GDBserver.
@@ -343,7 +349,7 @@ if { [info procs gdbserver_gdb_exit] == "" } {
     rename gdb_exit gdbserver_orig_gdb_exit
 }
 proc gdb_exit {} {
-    global gdb_spawn_id server_spawn_id
+    global gdb_spawn_id server_spawn_id inferior_spawn_id
     global gdb_prompt
 
     if {[info exists gdb_spawn_id] && [info exists server_spawn_id]} {
@@ -355,6 +361,7 @@ proc gdb_exit {} {
 	    -i "$server_spawn_id" eof {
 		wait -i $expect_out(spawn_id)
 		unset server_spawn_id
+		unset inferior_spawn_id
 	    }
 	}
     }
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]