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 C20F23858023 for ; Fri, 25 Aug 2023 15:35:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C20F23858023 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=1692977705; 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=TPLmFkI1mkXklU3yLz8EHP9NC2N6KwZEKNcKjyaeviE=; b=fNE/hQw2gnkBZkJ/LGeHTVDy8xxr9vdm+rlpp6DuA0SBFwlSp5kVvJvZHSsvA0oPT8N6HV ArpMf06ypVtO04kJiSzd28qpPoKkdT+hThhdPv2OPflZ/Hd86FiKJFWnQOKVQObp0Mgw4S DlvZbS1w59XWHkgiBVVTmpXnlNWqOGI= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-605-xVx9eMi2MFKwXiH0cX8ayA-1; Fri, 25 Aug 2023 11:35:04 -0400 X-MC-Unique: xVx9eMi2MFKwXiH0cX8ayA-1 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-3fef1bbfe93so7917885e9.0 for ; Fri, 25 Aug 2023 08:35:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692977702; x=1693582502; 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=TPLmFkI1mkXklU3yLz8EHP9NC2N6KwZEKNcKjyaeviE=; b=F+LCt0FTthtr8JklMJaQAYac7nnSLVTOwDSPJdm9OqWrirTHWnLTlo0fIXuPkzjR2+ WqFE8kZJJSOaCXpZaajBrZnK1Dbg7Zn3iHbuzMbLJDhqGDzrHaJB83n/3ocAfzn7LBdz PRc10A2my0nOexvRa5am4hGZyMGhq7NLUw8qXdwYdnh6Bu7kpD8cGOyzwOzA36PERzec vD3LKc8lf9EQHYRNppepQCrqgm0kqrhy3fKmktZ6C9N1CHx3u6uQa7+Rt3h4c3tX0035 v3boJxzFrMcSK0qUVnCVV3pjb+1BXlz1D+CWeAGveX7v0DOiYwaifRysqhfCa0xcNuUR uAkg== X-Gm-Message-State: AOJu0YwY6fyB3tSqA4tptj5Dn0/S10ZeOXcIZnrMQKGoBDJ+gn0RyCal Jip30FXYnsiH4tPYEum9SOe7gRLvUzvQw0a8MNC16NxYxAV1KxYnX7qFBIOUczN15VP1hL3Tqk0 6tvmn2/5Ozawg+/GTh42HVn3+yUHl3DrAAteMdueM+NAjdj+DPAAoblrIsdcJuUtI3wqmO1pMxb B3Oq/z4g== X-Received: by 2002:a7b:c389:0:b0:401:b0f2:88d5 with SMTP id s9-20020a7bc389000000b00401b0f288d5mr3512227wmj.32.1692977702545; Fri, 25 Aug 2023 08:35:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFCxC6tJZTvuhnUJ0k+gOXb4NaMNiCmPa4RfX527M+I5D0h771K0Lkptgh0pignC+ZIYlSEQg== X-Received: by 2002:a7b:c389:0:b0:401:b0f2:88d5 with SMTP id s9-20020a7bc389000000b00401b0f288d5mr3512204wmj.32.1692977701981; Fri, 25 Aug 2023 08:35:01 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id f23-20020a7bcd17000000b003feef82bbefsm2466462wmj.29.2023.08.25.08.35.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Aug 2023 08:35:01 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCHv2 09/10] gdb: use exec_file with remote targets when possible Date: Fri, 25 Aug 2023 16:34:42 +0100 Message-Id: <842a2c5acbee19501243a3fd3d152441c954cf41.1692977354.git.aburgess@redhat.com> 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 d5b758c888d..87ec0562bfb 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