diff options
Diffstat (limited to 'gdb/testsuite/gdb.server/fetch-exec-and-args.exp')
-rw-r--r-- | gdb/testsuite/gdb.server/fetch-exec-and-args.exp | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.server/fetch-exec-and-args.exp b/gdb/testsuite/gdb.server/fetch-exec-and-args.exp new file mode 100644 index 0000000..7c7750e --- /dev/null +++ b/gdb/testsuite/gdb.server/fetch-exec-and-args.exp @@ -0,0 +1,307 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2023 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/>. + +# Test the qExecAndArgs packet, specifically, the argument fetching +# component of the packet. + +# Skip test if target does not support argument passing. +require {!target_info exists noargs} + +load_lib gdbserver-support.exp + +standard_testfile + +require allow_gdbserver_tests + +if {[build_executable "failed to build" $binfile $srcfile]} { + return +} + +# Used as an override for extended_gdbserver_load_last_file in +# configs/native-extended-gdbserver.exp, prevents the remote exec-file +# from being set. +proc do_nothing {} { return 0 } + +# Check the 'show args' output. If PACKET is 'on' then we expect to +# see the arguments 'a b c', otherwise we don't expect to see any +# arguments. +proc check_show_args { packet } { + if { $packet } { + set args_re "a b c" + } else { + set args_re "" + } + + gdb_test "show args" \ + "Argument list to give program being debugged when it is started is \"$args_re\"\\." +} + +# Check the 'show remote exec-file' output. PACKET is either 'on' or +# 'off' and reflects whether the qExecAndArgs packet is turned on or +# off. FILENAME is what we expect to see included in the output, and +# is converted to a regexp by this function. +proc check_remote_exec_file { packet filename } { + if { $filename eq "" } { + if { $packet } { + set remote_exec_re \ + "The remote exec-file is unset, the remote has no default executable set\\." + } else { + set remote_exec_re \ + "The remote exec-file is unset, the default remote executable will be used\\." + } + } else { + set remote_exec_re \ + "The remote exec-file is \"[string_to_regexp $filename]\"\\." + } + + gdb_test "show remote exec-file" $remote_exec_re +} + +# Check the inferior has 4 arguments. Arg 0 will be the program name, +# while 1, 2, and 3 should be a, b, and c respectively. +proc check_full_args {} { + set exec_filename "" + gdb_test "print argc" " = 4" + gdb_test_multiple "print argv\[0\]" "" { + -re -wrap " = $::hex \"(.*/${::testfile})\"" { + set exec_filename $expect_out(1,string) + pass $gdb_test_name + } + } + gdb_test "print argv\[1\]" " = $::hex \"a\"" + gdb_test "print argv\[2\]" " = $::hex \"b\"" + gdb_test "print argv\[3\]" " = $::hex \"c\"" + + return $exec_filename +} + +# Close and cleanup gdbserver process. +proc cleanup_gdbserver {} { + catch { + close -i $server_spawn_id + wait -nowait -i $server_spawn_id + } +} + +# Check that GDB can fetch the arguments from the remote using the +# qExecAndArgs packet. When PACKET is 'on' we allow GDB to use the +# packet, but when PACKET is 'off' we disable use of the qExecAndArgs +# packet and ensure GDB falls back to the expected behaviour. +proc_with_prefix test_exec_and_arg_fetch { packet } { + clean_restart $::testfile + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + gdb_test "set remote fetch-exec-and-args ${packet}" \ + "Support for the 'qExecAndArgs' packet on future remote targets is set to \"${packet}\"\\." + + gdbserver_run "a b c" + + gdb_breakpoint $::srcfile:[gdb_get_line_number "Break here"] + gdb_continue_to_breakpoint "run to breakpoint" + + # Look in the inferior to check the arguments were passed + # correctly. We get back the name of the executable the inferior + # is running. If PACKET is 'on' then we expect GDB to have + # automatically fetched this executable name from the remote. + set exec_filename [check_full_args] + if { !$packet } { + set exec_filename "" + } + + # Check 'show args' to ensure GDB sees the correct arguments. + check_show_args $packet + + # Check 'show remote exec-file' to ensure GDB sees the correct + # filename. + check_remote_exec_file $packet $exec_filename + + # Below this point we rely on restarting the inferior, which + # relies on the extended-remote protocol. + if {[target_info gdb_protocol] ne "extended-remote"} { + cleanup_gdbserver + return + } + + with_test_prefix "rerun" { + # Don't restart GDB, but re-run the inferior. + gdb_run_cmd + gdb_test "" \ + "Breakpoint $::decimal, main \\(\[^)\]+\\).*" \ + "rerun until breakpoint in main" + + # If the packet is enabled then we expect the arguments to + # still be correct, otherwise, we should have defaulted back + # to no additional arguments. + if { $packet } { + check_full_args + } else { + gdb_test "print argc" " = 1" + } + + # Check 'show args' to ensure GDB sees the correct arguments. + check_show_args ${packet} + + # Check 'show remote exec-file' to ensure GDB sees the correct + # filename. + check_remote_exec_file $packet $exec_filename + } + + cleanup_gdbserver +} + +# With the extended-remote target it is possible to start gdbserver +# without specifying an inferior to run. In this case, gdbserver +# should reply to the qExecAndArgs packet with a 'U' (for unset) +# response. GDB should not override any currently set remote +# executable or inferior arguments. The benefit of this is that a +# user can set these values before connecting to gdbserver in this +# case. +proc_with_prefix test_exec_and_args_unset { packet } { + clean_restart + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + # Enable or disable the qExecAndArgs packet. + gdb_test "set remote fetch-exec-and-args ${packet}" \ + "Support for the 'qExecAndArgs' packet on future remote targets is set to \"${packet}\"\\." + + # Setup a remote exec-file value, and some inferior arguments. + set fake_exec_name "/xxx/yyy/zzz" + set fake_args "1 2 3" + gdb_test_no_output "set remote exec-file $fake_exec_name" + gdb_test_no_output "set args $fake_args" + + # Start gdbserver in extended-remote mode, don't specify an + # executable to start, or any inferior arguments. + set res [gdbserver_start "--multi" ""] + set gdbserver_protocol "extended-remote" + set gdbserver_gdbport [lindex $res 1] + gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport + + # Check within GDB that connecting to the extended-remote target + # didn't clobber the remote exec-file or inferior arguments. + gdb_test "show remote exec-file" \ + "The remote exec-file is \"[string_to_regexp $fake_exec_name]\"\\." + gdb_test "show args" \ + "Argument list to give program being debugged when it is started is \"${fake_args}\"\\." + + cleanup_gdbserver +} + +# Start GDB and set 'remote exec-file' to some random file. Then +# start gdbserver with the name of the actual executable. Connect to +# gdbserver from GDB and check that GDB gives a warning about the +# remove exec-file value having changed. +proc_with_prefix test_remote_exec_warning {} { + clean_restart + + gdb_test "disconnect" ".*" + + # Set the file GDB is going to debug. For extended-remote boards + # this also sets the remote exec-file. + gdb_file_cmd $::binfile + + set invalid_remote_exec "/xxx/yyy/zzz" + gdb_test_no_output "set remote exec-file $invalid_remote_exec" + check_remote_exec_file on $invalid_remote_exec + + # Start gdbserver. + set test "start gdbserver" + set target_exec [gdbserver_download_current_prog] + set target_exec_and_args "$target_exec a b c" + set catchres [catch {set res [gdbserver_start "" "$target_exec_and_args"]} errmsg] + if { $catchres != 0 } { + fail "$test: $errmsg" + } else { + pass "$test" + } + + # And connect to gdbserver. Check for the warning GDB emits when + # the remote exec-file is updated. + set gdbserver_protocol [lindex $res 0] + set gdbserver_gdbport [lindex $res 1] + set test "connect to gdbserver" + set extra_re "warning: updating 'remote exec-file' to '[string_to_regexp $target_exec]' to match remote target" + set res [gdb_target_cmd_ext $gdbserver_protocol $gdbserver_gdbport $extra_re] + if { $res == 0 } { + pass $test + } elseif { $res == 1 } { + fail $test + } else { + unsupported $test + } + + cleanup_gdbserver +} + +# Start GDB. When PACKET is 'off' disable the qExecAndArgs packet, +# otherwise, when PACKET is 'on' enable the packet. +# +# Start gdbserver in extended-remote mode, but don't provide a +# filename when starting gdbserver. +# +# Connect to the remote server, and check 'show remote exec-file'. +proc_with_prefix test_server_with_no_exec { packet set_remote_exec } { + clean_restart + + gdb_test "disconnect" ".*" + + gdb_file_cmd $::binfile + + gdb_test "set remote fetch-exec-and-args ${packet}" \ + "Support for the 'qExecAndArgs' packet on future remote targets is set to \"${packet}\"\\." + + # Start gdbserver. + set target_exec [gdbserver_download_current_prog] + + if { $set_remote_exec } { + gdb_test_no_output "set remote exec-file $target_exec" \ + "set remote exec-file" + set expected_filename $target_exec + } else { + set expected_filename "" + } + + gdbserver_start_extended + + check_remote_exec_file $packet $expected_filename +} + +# This override prevents the remote exec-file from being set when +# using the extended-remote protocol. This is harmless when using +# other boards. +with_override extended_gdbserver_load_last_file do_nothing { + # This override stops GDB connecting to the gdbserver as soon as + # GDB is started when testing with the extended-remote protocol. + with_override gdbserver_start_multi do_nothing { + foreach_with_prefix packet { on off } { + test_exec_and_args_unset $packet + test_exec_and_arg_fetch $packet + + foreach_with_prefix set_remote_exec { true false } { + test_server_with_no_exec $packet $set_remote_exec + } + } + + test_remote_exec_warning + } +} |