Make native gdbserver boards no longer be "remote" (in DejaGnu terms)
authorPedro Alves <palves@redhat.com>
Mon, 16 Oct 2017 19:24:21 +0000 (20:24 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 16 Oct 2017 19:24:21 +0000 (20:24 +0100)
This commit finally clears the "isremote" flag in the native-gdbserver
and native-stdio-gdbserver boards.  The goal is to make all "native"
boards be considered not remote in DejaGnu terms, like the
native-extended-gdbserver board is too.

DejaGnu automatically considers boards remote if their names don't
match the local hostname.  That means that native-gdbserver and
native-extended-gdbserver are considered remote by default by DejaGnu,
even though they run locally.  native-extended-gdbserver, however,
overrides its isremote flag to force it to be not remote.  So we are
in that weird state where native-gdbserver is considered remote, and
native-extended-gdbserver is considered not remote.

A recent set of commits fixed all the problems (and some more) exposed
by testing with --target_board=native-gdbserver and
--target_board=native-stdio-gdbserver with isremote forced off on
x86-64 GNU/Linux.  I believe we're good to go now.

The native-stdio-gdbserver.exp/remote-stdio-gdbserver.exp boards
required deep non-obvious modifications unfortunately...  The problem
is that if a board is not remote, then DejaGnu doesn't call
${board}_spawn / ${board}_exec at all, and the
native-stdio-gdbserver.exp board relies on those procedures being
called.  To fix that, this commit redesigns how the stdio boards hook
into the testing framework to spawn gdbserver.  IMO, this is a good
change anyway, because the way its done currently is a bit of a hack,
and the result turns out to be simpler, even.  With this commit, they
now no longer load the "gdbserver" generic config, and hook at the
mi_gdb_target_load/gdb_reload level instead, making them more like
traditional board files.

To share code between native-stdio-gdbserver.exp and
remote-stdio-gdbserver.exp, a new shared stdio-gdbserver-base.exp file
is created.

Instead of having each native board clear isremote manually, boards
source the new "local-board.exp" file.

This also adds a new section to testsuite/README file discussing
local/remote/native, so that we can easily refer to it.

gdb/testsuite/ChangeLog:
2017-10-16  Pedro Alves  <palves@redhat.com>
    Simon Marchi  <simon.marchi@polymtl.ca>

* README (Local vs Remote vs Native): New section.
* boards/local-board.exp: New file, with bits factored out from
...
* boards/native-extended-gdbserver.exp: ... here.  Load
"local-board".
* boards/native-gdbserver.exp: Load "local-board".
(${board}_spawn, ${board}_exec): Delete.
* boards/native-stdio-gdbserver.exp: Most contents factored out to
...
* boards/stdio-gdbserver-base.exp: ... this new file.
* boards/native-stdio-gdbserver.exp: Reimplement, by loading
"stdio-gdbserver-base" and defining a get_target_remote_pipe_cmd
procedure.
* boards/remote-stdio-gdbserver.exp: Load stdio-gdbserver-base
instead of native-stdio-gdbserver.  Don't set gdb_server_prog nor
stdio_gdbserver_command.
(${board}_get_remote_address, ${board}_get_comm_port)
(${board}_download, ${board}_upload): Delete.
(get_target_remote_pipe_cmd): New.

gdb/testsuite/ChangeLog
gdb/testsuite/README
gdb/testsuite/boards/local-board.exp [new file with mode: 0644]
gdb/testsuite/boards/native-extended-gdbserver.exp
gdb/testsuite/boards/native-gdbserver.exp
gdb/testsuite/boards/native-stdio-gdbserver.exp
gdb/testsuite/boards/remote-stdio-gdbserver.exp
gdb/testsuite/boards/stdio-gdbserver-base.exp [new file with mode: 0644]

index 6bcd5728440e336b3911136baa2d7a27698144e2..a4acfc674185cf1f6218234f8e3e53a89b6798dd 100644 (file)
@@ -1,3 +1,26 @@
+2017-10-16  Pedro Alves  <palves@redhat.com>
+           Simon Marchi  <simon.marchi@polymtl.ca>
+
+       * README (Local vs Remote vs Native): New section.
+       * boards/local-board.exp: New file, with bits factored out from
+       ...
+       * boards/native-extended-gdbserver.exp: ... here.  Load
+       "local-board".
+       * boards/native-gdbserver.exp: Load "local-board".
+       (${board}_spawn, ${board}_exec): Delete.
+       * boards/native-stdio-gdbserver.exp: Most contents factored out to
+       ...
+       * boards/stdio-gdbserver-base.exp: ... this new file.
+       * boards/native-stdio-gdbserver.exp: Reimplement, by loading
+       "stdio-gdbserver-base" and defining a get_target_remote_pipe_cmd
+       procedure.
+       * boards/remote-stdio-gdbserver.exp: Load stdio-gdbserver-base
+       instead of native-stdio-gdbserver.  Don't set gdb_server_prog nor
+       stdio_gdbserver_command.
+       (${board}_get_remote_address, ${board}_get_comm_port)
+       (${board}_download, ${board}_upload): Delete.
+       (get_target_remote_pipe_cmd): New.
+
 2017-10-16  Simon Marchi  <simon.marchi@ericsson.com>
 
        * gdb.python/py-breakpoint.exp (test_bkpt_basic,
index 037a340de4d878ba341edd4e12e286f339c0924b..4475ac21a9233c29d2e06750a313e42ef6481755 100644 (file)
@@ -579,3 +579,48 @@ Note that it is also acceptable, and often preferable, to avoid
 running the test at all.  This is the better option if the limitation
 is intrinsic to the environment, rather than a bug expected to be
 fixed in the near future.
+
+Local vs Remote vs Native
+*************************
+
+It's unfortunately easy to get confused in the testsuite about what's
+native and what's not, what's remote and what's not.  The confusion is
+caused by the overlap in vocabulary between DejaGnu and GDB.
+
+From a DejaGnu point of view:
+
+ - native: the host or target board is considered native if the its
+   triplet is the same as the build system's triplet,
+
+ - remote: the host or target board is considered remote if it's
+   running on a different machine, and thus require ssh, for example,
+   to run commands, versus simply running commands directly.
+
+Note that they are not mutually exclusive, as you can have a remote
+machine that has the same triplet as the build machine.
+
+From a GDB point of view:
+
+ - native: when GDB uses system calls such as ptrace to interact
+   directly with processes on the same system its running on,
+
+ - remote: when GDB speaks the RSP (Remote Serial Protocol) with
+   another program doing the ptrace stuff.
+
+Note that they are mutually exclusive.  An inferior can only be either
+debugged with the native target, or with the remote target a specific
+time.
+
+That means that there are cases where the target is not remote for
+DejaGnu, but is remote for GDB (e.g. running GDBserver on the same
+machine).
+
+You can also have a remote target for DejaGnu, but native for GDB
+(e.g.  building on x86 a GDB that runs on ARM and running the
+testsuite with a remote host).
+
+Therefore, care must be taken to check for the right kind of remote.
+Use [is_remote target] to check whether the DejaGnu target board is
+remote.  When what you really want to know is whether GDB is using the
+remote protocol, because feature X is only available when GDB debugs
+natively, check gdb_protocol instead.
diff --git a/gdb/testsuite/boards/local-board.exp b/gdb/testsuite/boards/local-board.exp
new file mode 100644 (file)
index 0000000..0af454b
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright 2011-2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# By default, DejaGnu makes the board remote unless the board name
+# matches localhost.  Sourcing this script from a board file forces
+# the board to be NOT remote.
+
+global board
+global board_info
+# Remove any target variant specifications from the name.
+set baseboard [lindex [split $board "/"] 0]
+set board_info($baseboard,isremote) 0
index 564ffd2229baed145da9c89c7ad1c0dfe48a7338..cf0ea47aca1b53f0f56378840403c3349ab05478 100644 (file)
 
 load_generic_config "extended-gdbserver"
 load_board_description "gdbserver-base"
-
-# By default, dejagnu makes the board remote unless the board name
-# matches localhost.  Force it to be NOT remote.
-global board
-global board_info
-# Remove any target variant specifications from the name.
-set baseboard [lindex [split $board "/"] 0]
-set board_info($baseboard,isremote) 0
+load_board_description "local-board"
 
 set_board_info sockethost "localhost:"
 
index e7c3d15e449bad3708bb605377f536ce087f3f97..093289d0689fa1c82338ca98181cfe80fbef9110 100644 (file)
@@ -22,6 +22,7 @@
 
 load_generic_config "gdbserver"
 load_board_description "gdbserver-base"
+load_board_description "local-board"
 
 # This gdbserver can only run a process once per session.
 set_board_info gdb,do_reload_on_run 1
@@ -35,27 +36,3 @@ set_board_info exit_is_reliable 1
 
 # We will be using the standard GDB remote protocol.
 set_board_info gdb_protocol "remote"
-
-proc ${board}_spawn { board cmd } {
-    global board_info
-
-    set baseboard [lindex [split $board "/"] 0]
-
-    set board_info($baseboard,isremote) 0
-    set result [remote_spawn $board $cmd]
-    set board_info($baseboard,isremote) 1
-
-    return $result
-}
-
-proc ${board}_exec { hostname program args } {
-    global board_info
-
-    set baseboard [lindex [split $hostname "/"] 0]
-
-    set board_info($baseboard,isremote) 0
-    set result [remote_exec $hostname $program $args]
-    set board_info($baseboard,isremote) 1
-
-    return $result
-}
index 4ab5b2895435aa14d018329c8aa0b64d785558e7..f8e7468bc01763fab03da85269bf68e2a24f50ef 100644 (file)
 # bash$ cd ${build_dir}/gdb
 # bash$ make check RUNTESTFLAGS="--target_board=native-stdio-gdbserver"
 
-load_generic_config "gdbserver"
-load_board_description "gdbserver-base"
+load_board_description "stdio-gdbserver-base"
 
-# This gdbserver can only run a process once per session.
-set_board_info gdb,do_reload_on_run 1
-
-# There's no support for argument-passing (yet).
-set_board_info noargs 1
-
-# Hack the host,port to pass our peculiar remote connection string.
-set_board_info sockethost ""
-set_board_info gdb,socketport "stdio"
-set_board_info gdb,get_remote_address ${board}_get_remote_address
-set_board_info gdbserver,get_comm_port ${board}_get_comm_port
-
-set_board_info use_gdb_stub 1
-set_board_info exit_is_reliable 1
-
-# We will be using the standard GDB remote protocol.
-set_board_info gdb_protocol "remote"
-
-# Used to pass a value between ${board}_spawn and ${board}_get_remote_address.
-set stdio_gdbserver_command "--unset--"
-
-proc ${board}_get_remote_address { host port } {
-    global stdio_gdbserver_command
-    return "| $stdio_gdbserver_command"
-}
-
-proc ${board}_get_comm_port { port } {
-    return $port
-}
-
-proc ${board}_spawn { board cmd } {
-    global board_info
-
-    verbose -log "${board}_spawn: $board $cmd"
-
-    # Save the command to start gdbserver for later retrieval by
-    # ${board}_get_remote_address.
-    global stdio_gdbserver_command
-    set stdio_gdbserver_command $cmd
-
-    set baseboard [lindex [split $board "/"] 0]
-
-    # We don't spawn gdbserver here, that is done by the subsequent
-    # "target remote | ..." command.
-    set board_info($baseboard,isremote) 0
-    # Pretend as if we've started gdbserver, provide the test harness
-    # with what it's waiting for.
-    set result [remote_spawn $board "echo Listening on stdio"]
-    set board_info($baseboard,isremote) 1
-
-    return $result
-}
-
-proc ${board}_exec { hostname program args } {
-    global board_info
-
-    set baseboard [lindex [split $hostname "/"] 0]
-
-    set board_info($baseboard,isremote) 0
-    set result [remote_exec $hostname $program $args]
-    set board_info($baseboard,isremote) 1
-
-    return $result
+proc get_target_remote_pipe_cmd {} {
+    global last_loaded_file
+    set gdbserver [find_gdbserver]
+    return "$gdbserver --once stdio $last_loaded_file"
 }
index 3d76829916e5548182ccfc9b653016615904fc27..7570dfe0f4f25127438103dba56a09ad7529600b 100644 (file)
@@ -24,7 +24,7 @@
 #    REMOTE_USERNAME=... REMOTE_HOSTNAME=... REMOTE_PORTNUM=... \
 #    [REMOTE_TMPDIR=${remote_dir}] [GDBSERVER=${remote_gdbserver}]"
 
-load_board_description "native-stdio-gdbserver"
+load_board_description "stdio-gdbserver-base"
 
 # Test machine info. The generic_config gdbserver reads some of these
 # values from board_info, so this file must set them there.
@@ -56,12 +56,6 @@ if [info exists REMOTE_TMPDIR] {
     set_board_info remotedir $REMOTE_TMPDIR
 }
 
-unset_board_info gdb_server_prog
-set_board_info gdb_server_prog "/usr/bin/gdbserver"
-
-# Used to pass a value between ${board}_spawn and ${board}_get_remote_address.
-set stdio_gdbserver_command "--unset--"
-
 proc get_remote_login { } {
     set result ""
     if {[board_info [target_info name] exists username]} {
@@ -73,27 +67,10 @@ proc get_remote_login { } {
     return $result
 }
 
-proc ${board}_get_remote_address { host port } {
-    global stdio_gdbserver_command
+proc get_target_remote_pipe_cmd { } {
+    set target_exec [gdbserver_download_current_prog]
     set rsh_cmd "[board_info [target_info name] rsh_prog] [get_remote_login]"
-    return "| $rsh_cmd $stdio_gdbserver_command"
-}
-
-proc ${board}_get_comm_port { port } {
-    return $port
-}
-
-proc ${board}_download { board host dest } {
-    if { [board_info [target_info name] exists remotedir] } {
-       set remotedir "[board_info [target_info name] remotedir]/"
-    } else {
-       set remotedir ""
-    }
-    return [standard_download $board $host "$remotedir$dest"]
-}
-
-proc ${board}_upload {dest srcfile args} {
-    return [standard_upload $dest $srcfile $args]
+    return "$rsh_cmd /usr/bin/gdbserver --once stdio $target_exec"
 }
 
 proc ${board}_file { dest op args } {
diff --git a/gdb/testsuite/boards/stdio-gdbserver-base.exp b/gdb/testsuite/boards/stdio-gdbserver-base.exp
new file mode 100644 (file)
index 0000000..f3bf25c
--- /dev/null
@@ -0,0 +1,54 @@
+# Copyright 2011-2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file has common bits shared between other dejagnu "board files"
+# that are used to run the testsuite with gdbserver connected via
+# stdio.  Boards that source this must reimplement the
+# get_target_remote_pipe_address procedure.
+
+load_board_description "gdbserver-base"
+
+# Note this is loaded for gdb_target_cmd, not for making this board
+# use the generic "gdbserver" config.
+load_lib gdbserver-support.exp
+
+# This gdbserver can only run a process once per session.
+set_board_info gdb,do_reload_on_run 1
+
+# There's no support for argument-passing (yet).
+set_board_info noargs 1
+
+set_board_info use_gdb_stub 1
+set_board_info exit_is_reliable 1
+
+# We will be using the standard GDB remote protocol.
+set_board_info gdb_protocol "remote"
+
+# Return the CMD string in "target remote | CMD".
+proc get_target_remote_pipe_cmd {} {
+    error "must reimplement this procedure"
+}
+
+proc make_gdbserver_stdio_port {} {
+    return "| [get_target_remote_pipe_cmd]"
+}
+
+proc gdb_reload { } {
+    return [gdb_target_cmd "remote" [make_gdbserver_stdio_port]]
+}
+
+proc mi_gdb_target_load { } {
+    return [mi_gdb_target_cmd "remote" [make_gdbserver_stdio_port]]
+}