aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-04-07 18:19:30 +0100
committerPedro Alves <palves@redhat.com>2015-04-07 18:28:38 +0100
commitf71c18e755dac28c61a5e5c94fbc8a84eb573679 (patch)
tree6fe77f411bef994213c7e43c959b681f3fbd8c9e
parent6423214fcb912a5d402ffcb84d6f61f2b900a900 (diff)
downloadgdb-f71c18e755dac28c61a5e5c94fbc8a84eb573679.zip
gdb-f71c18e755dac28c61a5e5c94fbc8a84eb573679.tar.gz
gdb-f71c18e755dac28c61a5e5c94fbc8a84eb573679.tar.bz2
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-04-07 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.
-rw-r--r--gdb/testsuite/ChangeLog11
-rw-r--r--gdb/testsuite/lib/gdb.exp51
-rw-r--r--gdb/testsuite/lib/gdbserver-support.exp11
3 files changed, 69 insertions, 4 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index eb084d2..d172857 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,16 @@
2015-04-07 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.
+
+2015-04-07 Pedro Alves <palves@redhat.com>
+
* lib/gdb.exp (gdb_finish): Delete persistent gdbserver handling.
* lib/gdbserver-support.exp (gdbserver_start): Make
$server_spawn_id global.
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 1669f45..f1616e3 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
}
@@ -656,13 +664,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
@@ -723,7 +749,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
@@ -820,6 +846,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."
@@ -1465,6 +1494,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
@@ -1475,6 +1505,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.
@@ -3206,6 +3241,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
}
}
}