From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 5204E38555B2 for ; Wed, 16 Aug 2023 15:55:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5204E38555B2 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1692201328; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w8q4xeXmWYT/ji8ASbpK1KZZDEZePJ8gf/TloWkuiv8=; b=IBRNM4hfJbWfuyAYKO5dYSWunvGngzaj2OIO2tfPGLV4T8r62W6uctD/AOKcXt7dXCj+PW RC5fqPcwvPHnB+xe0wc3c3gb8mpKZOi/hKV4wwfGLbXe/xlKnlti0oHv6/VsPEnsOwO5CR vZlS5IfIWm9eVzJQc+pSoHyHTbqBoW4= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-449-my3_PbmjN3uoWJKCxwtZZA-1; Wed, 16 Aug 2023 11:55:25 -0400 X-MC-Unique: my3_PbmjN3uoWJKCxwtZZA-1 Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-978a991c3f5so46260366b.0 for ; Wed, 16 Aug 2023 08:55:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692201323; x=1692806123; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=w8q4xeXmWYT/ji8ASbpK1KZZDEZePJ8gf/TloWkuiv8=; b=eDRV8gW/oCZYj+bFJQ4q8HsPgL2NbWK6vrokwMzt6kNr3+QhqqDdXdV45X5N/9y8uC OcogONS31B1HkCBWBLd3OE0F6zY8YRICtgSp+Z9EljClt9ZTKGRiH2Pgmnw6fjK3+Ve0 2wLZ42ekIm8mtklkuLOhSDkkXleC8QZcRiOZCwrsl+lkHuSm5Dw1gTELVpq2kRJm7/XT PNAqDpv7PSvPKWcyKxM/5MiodnP4H5qVnU9xXttTmVp30S/Mv9XlIzpdenkWko73+sDV Kv+X5qnQ95oX8movPvHCcX+ct4b2BnoYImIHIq87h8rfdvO0tlCkTCOT9WGvSHiMT5mM f+5g== X-Gm-Message-State: AOJu0YzH7ogxMDJoO6aJJ9ju9KPFm/WvThN3U8LuAPOT+N+/CGubce6f I0xIo53c06PlEPobN/d8HGhsteW2SiCdkNExYCBugRVU1mORVryCCM/wOy9TURCd1SjbikvOkz+ H1NnQKCzJ4hes0ACySvPh30gSV3HWZhvwQHZ1ypgmJmIQw2MG/zUVpV/SmxhIEoYxzrH4Mmv31y pFaYR/gw== X-Received: by 2002:a17:906:7b42:b0:99b:dd1d:64ba with SMTP id n2-20020a1709067b4200b0099bdd1d64bamr1838149ejo.50.1692201323667; Wed, 16 Aug 2023 08:55:23 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHSKtIsCsijb7QI9K8MAjDmvrLdZdawxSocl8TepIF4qslB9mU4JZRWknLVpgR5kHTYzDi//w== X-Received: by 2002:a17:906:7b42:b0:99b:dd1d:64ba with SMTP id n2-20020a1709067b4200b0099bdd1d64bamr1838140ejo.50.1692201323372; Wed, 16 Aug 2023 08:55:23 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id lj5-20020a170906f9c500b0098d2d219649sm8794265ejb.174.2023.08.16.08.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 08:55:22 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 09/10] gdb: use exec_file with remote targets when possible Date: Wed, 16 Aug 2023 16:55:05 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This commit allows GDB to make use of the file set with the 'file' command when starting a new inferior on an extended-remote target. There are however some restrictions. If the user has used 'set remote exec-file', then this is always used in preference to the file set with the 'file' command. Similarly, if the qDefaultExecAndArgs packet has succeeded, and GDB knows that the remote target has a default executable set, then this will be used in preference to the file set with the 'file' command; this preserves GDB's existing behaviour. And, GDB can only use the file set with the 'file' command if it believes that both GDB and the remote target will both be able to access this file. This means that either, the sysroot has been updated by the user and no longer contains a 'target:' prefix, or, the the remote_target::filesystem_is_local function returns true (see the implementation of that function for details of when this can happen). If all of these conditions are met, then GDB will use the file set with the 'file' command when starting a new inferior, in all other cases, GDB will use the file set with 'set remote exec-file'. --- gdb/remote.c | 52 ++++++++++- gdb/testsuite/gdb.server/ext-run.exp | 131 +++++++++++++++++++++------ 2 files changed, 154 insertions(+), 29 deletions(-) diff --git a/gdb/remote.c b/gdb/remote.c index 1d5e098e91f..e2d21c65b70 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1396,6 +1396,9 @@ class extended_remote_target final : public remote_target void post_attach (int) override; bool supports_disable_randomization () override; + +private: + std::string get_exec_file_for_create_inferior (const char *exec_file); }; struct stop_reply : public notif_event @@ -11031,6 +11034,51 @@ directory: %s"), } } +/* Return the path for the executable that GDB should ask the remote target + to use when starting an inferior. EXEC_FILE is GDB's idea of the + current inferior (e.g. set with the 'file' command), however, this is + often not the right thing for a remote target to use, which is why GDB + also has the 'set remote exec-file' command. + + If the user has 'set remote exec-file', then this function returns the + path the user set. Otherwise, if it is possible that GDB and the remote + target can see the same filesystem, this function will return + EXEC_FILE. */ + +std::string +extended_remote_target::get_exec_file_for_create_inferior + (const char *exec_file) +{ + const remote_exec_file_info &info + = get_remote_exec_file_info (current_program_space); + + /* If INFO.SECOND is remote_exec_source::DEFAULT_VALUE, then this + indicates that the remote target has failed to inform us if it has a + default-executable set or not, maybe the remote doesn't support the + qDefaultExecAndArgs packet? In this case, we pass the empty string to + the remote and expect it to use the default executable (if one is + set). */ + if (exec_file != nullptr + && info.second == remote_exec_source::UNSET_VALUE) + { + /* If the sysroot has been set to something that does not have a + 'target:' prefix then GDB will not be trying to fetch files from + the remote anyway, so we can assume that the executable is visible + to both the remote and GDB. + + Otherwise, if GDB is able to determine that the remote filesystem + is actually local, then we are still OK to use the local + executable. */ + if (!is_target_filename (gdb_sysroot) + || target_filesystem_is_local ()) + return exec_file; + } + + /* The user has set the remote exec-file, or GDB doesn't think the remote + target and GDB can see the same filesystem. */ + return info.first; +} + /* In the extended protocol we want to be able to do things like "run" and have them basically work as expected. So we need a special create_inferior function. We support changing the @@ -11045,7 +11093,9 @@ extended_remote_target::create_inferior (const char *exec_file, int run_worked; char *stop_reply; struct remote_state *rs = get_remote_state (); - const std::string &remote_exec_file = get_remote_exec_file (); + + std::string remote_exec_file + = get_exec_file_for_create_inferior (exec_file); /* If running asynchronously, register the target file descriptor with the event loop. */ diff --git a/gdb/testsuite/gdb.server/ext-run.exp b/gdb/testsuite/gdb.server/ext-run.exp index 59ead666d7b..3a4bf3e7eb1 100644 --- a/gdb/testsuite/gdb.server/ext-run.exp +++ b/gdb/testsuite/gdb.server/ext-run.exp @@ -30,43 +30,118 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { # allow_xml_test must be called while gdb is not running. set do_xml_test [allow_xml_test] -save_vars { GDBFLAGS } { - # If GDB and GDBserver are both running locally, set the sysroot to avoid - # reading files via the remote protocol. - if { ![is_remote host] && ![is_remote target] } { - set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" +# This is used as an override function. +proc do_nothing {} { return 0 } + +# Start an exetended-remote gdbserver, connect to it, and then use +# 'run' to start an inferior. +# +# If CLEAR_SYSROOT is true then the 'set sysroot' command is issued, +# clearing the sysroot, otherwise the sysroot is left unchanged. +# +# If SET_REMOTE_EXEC is true then the 'set remote-exec ...' command is +# issued to point GDB at the executable on the target (after copying +# the executable over). Otherwise, we rely on GDB and gdbserver being +# able to see the same filesystem, remote exec-file is not set, and +# GDB will just use the path to the executable. +proc do_test { clear_sysroot set_remote_exec fetch_exec_and_args } { + save_vars { ::GDBFLAGS } { + if { $clear_sysroot } { + set ::GDBFLAGS "$::GDBFLAGS -ex \"set sysroot\"" + } + + clean_restart $::binfile } - clean_restart $binfile -} + # Disable, or enable, use of the qDefaultExecAndArgs packet. + gdb_test "set remote fetch-exec-and-args-packet ${fetch_exec_and_args}" \ + ".*" -# Make sure we're disconnected, in case we're testing with an -# extended-remote board, therefore already connected. -gdb_test "disconnect" ".*" + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" -set target_exec [gdbserver_download_current_prog] -gdbserver_start_extended + gdbserver_start_extended -gdb_test_no_output "set remote exec-file $target_exec" "set remote exec-file" + gdb_test "show remote exec-file" \ + "The remote exec-file is \"\"\[^\r\n\]*" \ + "check remote exec-file is unset" -gdb_breakpoint main -gdb_test "run" "Breakpoint.* main .*" "continue to main" + if { $set_remote_exec } { + set target_exec [gdbserver_download_current_prog] + gdb_test_no_output "set remote exec-file $target_exec" \ + "set remote exec-file" + } -if { [istarget *-*-linux*] } { - # On Linux, gdbserver can also report the list of processes. - # But only if xml support is compiled in. - if { $do_xml_test } { - # This is done in a way to avoid the timeout that can occur from - # applying .* regexp to large output. - gdb_test_sequence "info os processes" "get process list" \ - { "pid +user +command" "1 +root +\[/a-z\]*(init|systemd)" } + gdb_breakpoint main + gdb_test_multiple "run" "continue to main" { + -re -wrap "Breakpoint.* main .*" { + pass $gdb_test_name + } + -re -wrap "Running the default executable on the remote target failed; try \"set remote exec-file\"." { + + # If 'set remote exec-file' has been used then we should + # not get here. + gdb_assert {!$set_remote_exec} \ + "confirm remote exec-file is not set" + + if {!$fetch_exec_and_args} { + # We deliberately disabled GDB's ability to know that + # the remote doesn't have a default executable set (by + # disabling the qDefaultExecAndArgs packet). We got + # the result we expected, but the inferior is not + # running, so we're done with this phase of testing. + pass $gdb_test_name + return + } else { + # This means that the qMachineId packet is not supported, + # and GDB could not tell if it is running on the same host + # as gdbserver. Confirm that qMachineId is showing as + # disabled, and then move onto the next testing mode. + gdb_test "show remote fetch-machine-id-packet" \ + "Support for the 'qMachineId' packet on the current remote target is \"auto\", currently disabled\\." \ + "confirm qMachineId packet is not supported" + return + } + } + } + + if { [istarget *-*-linux*] } { + # On Linux, gdbserver can also report the list of processes. + # But only if xml support is compiled in. + if { $::do_xml_test } { + # This is done in a way to avoid the timeout that can occur from + # applying .* regexp to large output. + gdb_test_sequence "info os processes" "get process list" \ + { "pid +user +command" "1 +root +\[/a-z\]*(init|systemd)" } + } } -} -gdb_test "kill" "" "kill" "Kill the program being debugged. .y or n. " "y" + gdb_test "kill" "" "kill" "Kill the program being debugged. .y or n. " "y" -gdb_load $binfile -gdb_test "monitor help" "The following monitor commands.*" \ + gdb_load $::binfile + gdb_test "monitor help" "The following monitor commands.*" \ "load new file without any gdbserver inferior" -gdb_test_no_output "monitor exit" + gdb_test_no_output "monitor exit" +} + +set clear_sysroot_modes { false } +set set_remote_exec_modes { true } +if {![is_remote target] && ![is_remote host]} { + lappend set_remote_exec_modes false + lappend clear_sysroot_modes true +} + +# This override prevents GDB from automatically setting the 'remote +# exec-file' when using the extended-remote protocol. If we want the +# exec-file set, then this test takes care of it. +with_override extended_gdbserver_load_last_file do_nothing { + foreach_with_prefix clear_sysroot $clear_sysroot_modes { + foreach_with_prefix set_remote_exec $set_remote_exec_modes { + foreach_with_prefix fetch_exec_and_args { on off } { + do_test $clear_sysroot $set_remote_exec $fetch_exec_and_args + } + } + } +} -- 2.25.4