+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.
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
}
# }
# }
#
+# 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
lappend processed_code $item
continue
}
- if { $item == "-timeout" } {
+ if { $item == "-timeout" || $item == "-i" } {
set expecting_arg 1
lappend processed_code $item
continue
}
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."
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
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.
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 ""
+ }
+}
+
#
#
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
# 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
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.
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]} {
-i "$server_spawn_id" eof {
wait -i $expect_out(spawn_id)
unset server_spawn_id
+ unset inferior_spawn_id
}
}
}