From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id QW1qAamdHWk0xBIAWB0awg (envelope-from ) for ; Wed, 19 Nov 2025 05:36:25 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ADFRbfMD; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 00CC61E0B6; Wed, 19 Nov 2025 05:36:24 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 8E6E81E08D for ; Wed, 19 Nov 2025 05:36:23 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 35149384D17D for ; Wed, 19 Nov 2025 10:36:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 35149384D17D Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ADFRbfMD Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id F3FE3384D161 for ; Wed, 19 Nov 2025 10:32:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F3FE3384D161 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F3FE3384D161 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1763548377; cv=none; b=kCwpvtsS+DY4LRES61+4iU6TdISzNdnfbEXDUAkKApdXbQUfuFXWKkOrFbMz0g37U9skHV4s2rOstEc1GHAYfjkT9ULE8YfQwl5dqnD7uoRRJ42fSoaydowPWyB4G5G9/gf7v9z3I900QveVYQQ1H2OR5Hml7dzdooVChvhyApU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1763548377; c=relaxed/simple; bh=e6V2pOO3+mJT1pgRIwq9q92yJ9nUOM8HaTViwZ7xtTg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=PKbcvTl7IW5m9otXuBibRoESkWpV+In+PipRu63IfqskC9OneIAy4OIPhLDSj2B+LaxY/Oiin8wUDLpQ/OaqQtnB4XZWWflyqa0XknE2047iv/AZq8sCuGaEsWQeJlj57nGLO7gb+MCrpos+owFFr/obHF4ao36QsfMIk6WkgcE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3FE3384D161 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1763548376; 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=u1tWMMTyCjARllC9+9I9hVS/zRaQYArnF4LjL509pw4=; b=ADFRbfMD2iXzGH6D+FUvYTpFmRl+vFudXVQPXISVEbfbXaaDyyWP+HfpsXdzM/iAG+9qBL sLNx9g37Bn8Nv76chTXzvyrbWdh47EvGtXzOSrI+gWblG4uDfLZ3Z6w8gqR91SaSdmB/H5 mVM9QlqQpv5Ab5FJRZfDOu1NWRehdcU= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-445-USF_WpGiN9C1VJBgf9b5hw-1; Wed, 19 Nov 2025 05:32:53 -0500 X-MC-Unique: USF_WpGiN9C1VJBgf9b5hw-1 X-Mimecast-MFC-AGG-ID: USF_WpGiN9C1VJBgf9b5hw_1763548372 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-42b366a76ffso3426237f8f.1 for ; Wed, 19 Nov 2025 02:32:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763548371; x=1764153171; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=u1tWMMTyCjARllC9+9I9hVS/zRaQYArnF4LjL509pw4=; b=N0CAAa0sKjH+EJ2xG2dqneguwSPhJ7T2qdFq/NAvx+9fYO3geIo+ltqXriQC3lCb1T xPtsCMXD1gYE6bLUTiudjlTl/1n2EjZGXD2RKc51julxjN+hISSKfaXwcaxmyeTINHdR wKxyzBVxER/XySFZgzNUron8bNBBti28M8mBzwfquAHBpmAsEvSYgGzFgnYr9Jnu/EoZ xD5Y6UGnMx9ol+XTNUPdziLxNC5yzxNi4KzU08IhsMMqdFsdOXCCLeFssBCsRnq8Zsh9 F+j/SNaWnI8OMqyx9LOgxWorlAByVarluWcdDQElNXk+xr5ibDAwhvrOFMPYzZ1yaIJ9 RixQ== X-Gm-Message-State: AOJu0YxlcI1VGVNLlbYwnzi3mviXwdQPfTILE8j3VtQtM/z0jHCIocjQ X6y38iOm0E01p4aggwYPUClmZI7ICGwdivQVtWFAGJ/jAg9drp04f6qFY5i10Ff6un2e48sHIqZ p9Ode26rEs/5cBtVste/TG5wjRfs9RK7W81UN7YRokQsJ83NREUwbl/QHtuNP3MexhIXeoZpJ4Z 8bwjUrM6F9UUKYSLF24NMhxp1p8Fa1sVNeukdOKHOzaVRJa54= X-Gm-Gg: ASbGnctWk9y9oJLDLQJDMj+Qf/P+N/iShb9rSVmhI/7vPwP2O+xF9ALaanx6quc9+Wt iPtg4cRRKPcTt/+ick1ZZGmEsk5Dz1okUcrBITh36dX03ZspCAPidBL7mM0HYLob+wiFKm7PgOd 3JBNn0SAZGuVtxWykyRSoTOkSXsadE7JvoA9qg5HlX9AguE2FqMHYtqZ1/rCj9QiY2s8W3vDBY4 msBnFYTMqfQQwnwohqKFL0ruMYHvZqNYRVRVvDbrz85FAWIlcOcw6V0ARNhjyipDQSLlBd/S5Pk TtyTnn5QrtMcmSv/2B7eMVHpMrzbCbDqbi2x2XSFxVzN+K5EFdn7NAHLhk9Iu+FqBUZpr250qIM ieaUi X-Received: by 2002:a05:6000:4020:b0:42b:3ee9:4771 with SMTP id ffacd0b85a97d-42b593503ffmr19362844f8f.23.1763548370921; Wed, 19 Nov 2025 02:32:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IFDiWznj3LVmS7WmVl6aw+zPkNfiWd23QlUvfcGn+4oJm4o5TZdljjO7VIDMRe9WZegLecP6g== X-Received: by 2002:a05:6000:4020:b0:42b:3ee9:4771 with SMTP id ffacd0b85a97d-42b593503ffmr19362805f8f.23.1763548370195; Wed, 19 Nov 2025 02:32:50 -0800 (PST) Received: from localhost ([31.111.84.207]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-42c9628ebacsm24381295f8f.30.2025.11.19.02.32.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Nov 2025 02:32:49 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , Eli Zaretskii Subject: [PATCH 2/2] gdb: use current executable for 'remote exec-file' in some cases Date: Wed, 19 Nov 2025 10:32:40 +0000 Message-ID: X-Mailer: git-send-email 2.47.1 In-Reply-To: References: <40cbbd9f0082b07e9767656fe044bbe9280983a3.1759763251.git.aburgess@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: JuGPSnxIvoHhou7R_nGxaGHThHMrtyzJoy7TDtdIdaA_1763548372 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Message-ID: <20251119103240.mnGA0VMn7Q-D1fxOdUtVnjIosmNw3xcVJ4nzeM7XbUg@z> 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 setting is always used in preference to the file set with the 'file' command. Similarly, if the qExecAndArgs packet has succeeded, and GDB knows that the remote target has an executable set, then this will be used in preference to the file set with the 'file' command; this preserves GDB's existing behaviour. In effect, when GDB connects to the remote target, the remote sets the 'remote exec-file' and this prevents GDB from using the 'file' filename. 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 one of these is true: + the the remote_target::filesystem_is_local function returns true (see the implementation of that function for details of when this can happen). This means GDB and the remote target can see the same file system, GDB can just use the current executable's filename as is, or + the user has set the 'file' to something with a 'target:' prefix, e.g. 'file target:/path/to/exec'. In this last case, GDB will use the exec filename without the 'target:' prefix, this filename is, by definition, something the remote target can see, or + the sysroot has been updated by the user and no longer contains a 'target:' prefix. In this case, if the 'file' filename is within the sysroot, then it is assumed the remote will also be able to see a file with the same filename. For example, if the sysroot is '/aa/', and the current executable is '/aa/bb/cc', then GDB will tell the remote to run '/bb/cc'. One common case here is when the sysroot is set to the empty string, which is usually done when GDB and the remote target can see the same filesystem, in this case GDB will use the current executable's filename unmodified. If one of these conditions is met, then GDB will use the current executable's filename (with possible modifications as mentioned above), when starting a new extended-remote inferior, in all other cases, GDB will use the file name set with 'set remote exec-file'. This change could be useful any time a user is running a remote target on the same machine as GDB, but I am specifically thinking of the case where GDB is using a tool other than gdbserver, e.g. valgrind, as this saves one additional step that a user must remember. The current steps to start valgrind with GDB, as given on the valgrind website (https://valgrind.org/docs/manual/manual-core-adv.html) are: $ gdb prog (gdb) set remote exec-file prog (gdb) set sysroot / (gdb) target extended-remote | vgdb --multi --vargs -q (gdb) start With this GDB work, and once support for the qExecAndArgs packet is added to valgrind, then the 'set remote exec-file' line can be dropped from those instructions. This commit also extends the 'show remote exec-file' command so that GDB will display the automatic value that it plans to use. Here's an example of the new output: $ gdb -q /tmp/hello Reading symbols from /tmp/hello... (gdb) set sysroot (gdb) target extended-remote | ./gdbserver/gdbserver --multi --once - Remote debugging using | ./gdbserver/gdbserver --multi --once - Remote debugging using stdio (gdb) show remote exec-file The remote exec-file is unset, using automatic value "/tmp/hello". The last line shows the new output. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 8 ++ gdb/doc/gdb.texinfo | 4 +- gdb/remote.c | 156 +++++++++++++++++++++++--- gdb/testsuite/gdb.server/ext-run.exp | 160 ++++++++++++++++++++++----- 4 files changed, 286 insertions(+), 42 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index b0146852c5c..58a5b3c2496 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -31,6 +31,14 @@ subsequent runs of the inferior will use the same arguments as the first run. +* When connected to an extended-remote target GDB can now + automatically set the 'remote exec-file' in some cases. GDB will + auto set the remote exec-file only if the remote wasn't started with + an executable, and the user hasn't used 'set remote exec-file' to + set an executable. GDB will auto set the remote exec-file using the + current executable if the current executable has a 'target:' prefix, + or if the current executable is within the sysroot. + * New targets GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux* diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 1b463b167e7..efd9d80de07 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -24668,7 +24668,9 @@ Remote Configuration Select the file used for @code{run} with @code{target extended-remote}. This should be set to a filename valid on the target system. If it is not set, the target will use a default -filename (e.g.@: the last program run). +filename (e.g.@: the last program run, or a filename derived from the +current executable if @value{GDBN} and the remote can see the same +file system). When connecting to a remote system, with @kbd{target extended-remote} or @kbd{target remote}, if the remote server supports the diff --git a/gdb/remote.c b/gdb/remote.c index 143835ad503..2c77405305e 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -43,9 +43,11 @@ #include "target-descriptions.h" #include "gdb_bfd.h" #include "gdbsupport/filestuff.h" +#include "gdbsupport/pathstuff.h" #include "gdbsupport/rsp-low.h" #include "disasm.h" #include "location.h" +#include "filenames.h" #include "gdbsupport/gdb_sys_time.h" @@ -1555,8 +1557,49 @@ class extended_remote_target final : public remote_target void post_attach (int) override; bool supports_disable_randomization () override; + + /* Return the file name for the executable that GDB should ask the remote + target to use when starting an inferior. + + EXEC_FILE is the string passed from GDB core, which is the file name + of the current executable, which can be NULL. + + If the user has done 'set remote exec-file', or the remote told GDB + which executable to use via the 'qExecAndArgs' packet, then this is + the value returned by this function, EXEC_FILE is ignored. + + But if there is no remote exec-file set, then we might be able to use + EXEC_FILE, or a variation of EXEC_FILE, as the 'remote exec-file' + setting. This will depend on the value of EXEC_FILE and/or the + current gdb_sysroot setting. In this case the file name derived from + EXEC_FILE is returned. + + If neither approach comes up with a suitable file name to run then + the empty string is returned. */ + + std::string get_exec_file_for_create_inferior (const char *exec_file); }; +/* Get a pointer to the current remote target. If not connected to a + remote target, return NULL. */ + +static remote_target * +get_current_remote_target () +{ + target_ops *proc_target = current_inferior ()->process_target (); + return dynamic_cast (proc_target); +} + +/* Get a pointer to the current remote target. If not connected to a + remote target, return NULL. */ + +static extended_remote_target * +get_current_extended_remote_target () +{ + target_ops *proc_target = current_inferior ()->process_target (); + return dynamic_cast (proc_target); +} + struct stop_reply : public notif_event { /* The identifier of the thread about this event */ @@ -2044,8 +2087,25 @@ show_remote_exec_file (struct ui_file *file, int from_tty, gdb_printf (file, _("The remote exec-file is unset, the default " "remote executable will be used.\n")); else if (info.source == remote_exec_source::UNSET_VALUE) - gdb_printf (file, _("The remote exec-file is unset, the remote has " - "no default executable set.\n")); + { + std::string remote_exec_filename; + extended_remote_target *remote = get_current_extended_remote_target (); + if (remote != nullptr) + { + const char *exec_file = current_program_space->exec_filename (); + remote_exec_filename + = remote->get_exec_file_for_create_inferior (exec_file); + } + + if (!remote_exec_filename.empty ()) + gdb_printf (file, _("The remote exec-file is unset, using " + "automatic value \"%ps\".\n"), + styled_string (file_name_style.style (), + remote_exec_filename.c_str ())); + else + gdb_printf (file, _("The remote exec-file is unset, the remote has " + "no default executable set.\n")); + } else gdb_printf (file, _("The remote exec-file is \"%ps\".\n"), styled_string (file_name_style.style (), @@ -2151,16 +2211,6 @@ remote_arch_state::remote_arch_state (struct gdbarch *gdbarch) this->remote_packet_size = (this->sizeof_g_packet * 2 + 32); } -/* Get a pointer to the current remote target. If not connected to a - remote target, return NULL. */ - -static remote_target * -get_current_remote_target () -{ - target_ops *proc_target = current_inferior ()->process_target (); - return dynamic_cast (proc_target); -} - /* Return the current allowed size of a remote packet. This is inferred from the current architecture, and should be used to limit the length of outgoing packets. */ @@ -11319,6 +11369,84 @@ directory: %s"), } } +/* See class declaration above. */ + +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); + + /* Historically, when the remote target started a new inferior GDB would + ignore the filename from GDB core (EXEC_FILE) and would use whatever + value the user had set in 'remote exec-file'. Now we try to be + smarter. + + Obviously, if 'remote exec-file' has been set, then this should be + considered definitive. But if 'remote exec-file' has not been set, + then, in some cases, we might be able to use EXEC_FILE, or a + derivative of EXEC_FILE. + + It can also happen that EXEC_FILE is NULL. This is mostly a bit of an + edge case where GDB has attached to a running process, and couldn't + figure out the filename for the executable. If the user then does + 'run' we could end up with EXEC_FILE being NULL. If this happens then + the only option is to use the 'remote exec-file' setting. + + If INFO.SOURCE is ::VALUE_FROM_REMOTE or ::VALUE_FROM_GDB then there + is a value in 'remote exec-file', we should not do anything with + EXEC_FILE and just retain the 'remote exec-file' value. + + If INFO.SOURCE is ::UNSET_VALUE then the user hasn't 'set remote + exec-file' value, and the remote target has specifically told us (via + the qExecAndArgs packet) that it has no default executable set. In + this case, if GDB and the remote can see the same filesystem, we can + potentially use EXEC_FILE. + + If INFO.SOURCE is ::DEFAULT_VALUE then the user hasn't set a 'remote + exec-file' value, but the remote target was unable to tell us (maybe + the qExecAndArgs packet isn't supported) if it has a default + executable set. We might be tempted to treat this like the + ::UNSET_VALUE case, however, this could potentially break backward + compatibility in the case where the remote does have a default + executable set. To maintain compatibility, we send over the 'remote + exec-file' setting, whatever it might be. */ + if (exec_file != nullptr + && info.source == remote_exec_source::UNSET_VALUE) + { + /* If the user has set the core exec file to a file on the target + then we can just strip the target prefix and use that as the + remote exec file name. */ + if (is_target_filename (exec_file)) + return exec_file + strlen (TARGET_SYSROOT_PREFIX); + + /* If the target filesystem is local then the remote can see + everything GDB can see. In this case the remote should be able to + access EXEC_FILE. */ + if (target_filesystem_is_local ()) + return exec_file; + + /* If the sysroot is not a target path, then GDB can see a copy of + the remote target's filesystem, or if sysroot is empty, then the + remote and GDB could be sharing a filesystem. + + In either case, by removing the sysroot from the front of + EXEC_FILE, we can build a filename that the remote can see. */ + if (!is_target_filename (gdb_sysroot)) + { + const char *in_sysroot_path = child_path (gdb_sysroot.c_str (), + exec_file); + if (in_sysroot_path != nullptr) + return path_join ("/", in_sysroot_path); + } + } + + /* 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.filename; +} + /* 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 @@ -11333,7 +11461,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 f4ff546c393..18205e11ec8 100644 --- a/gdb/testsuite/gdb.server/ext-run.exp +++ b/gdb/testsuite/gdb.server/ext-run.exp @@ -30,43 +30,147 @@ 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 } { + + # If we don't clear the sysroot, then the sysroot will remain as + # 'target:'. In this case, if we don't 'set remote exec-file' + # then GDB will not be able to start a remote inferior. + if { !$clear_sysroot && !$set_remote_exec } { + return } clean_restart $::testfile -} -# Make sure we're disconnected, in case we're testing with an -# extended-remote board, therefore already connected. -gdb_test "disconnect" ".*" + # Disable, or enable, use of the qExecAndArgs packet. + gdb_test "set remote fetch-exec-and-args-packet ${fetch_exec_and_args}" \ + ".*" -set target_exec [gdbserver_download_current_prog] -gdbserver_start_extended + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" -gdb_test_no_output "set remote exec-file $target_exec" "set remote exec-file" + if { $clear_sysroot } { + gdb_test_no_output "set sysroot" \ + "clear sysroot" + } else { + set sysroot "UNKNOWN" + gdb_test_multiple "show sysroot" "" { + -re -wrap "^The current system root is \"(\[^\r\n\]*)\"\\." { + set sysroot $expect_out(1,string) + pass $gdb_test_name + } + } -gdb_breakpoint main -gdb_test "run" "Breakpoint.* main .*" "continue to main" - -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_lines "info os processes" "get process list" \ - "^pid +user +command.*\r\n1 +root +\[/a-z\]*(init|systemd|bash)" + if { $sysroot eq "" } { + gdb_test_no_output "set sysroot target:" + } elseif { $sysroot ne "target:" } { + unsupported "unexpected sysroot value" + return + } } -} -gdb_test "kill" "" "kill" "Kill the program being debugged. .y or n. " "y" + gdbserver_start_extended -gdb_load $binfile -gdb_test "monitor help" "The following monitor commands.*" \ + # Check the 'remote exec-file' setting before we (possibly) set it + # ourselves. + if { !$fetch_exec_and_args } { + set suffix "the default remote executable will be used" + } elseif { !$clear_sysroot} { + set suffix "the remote has no default executable set" + } else { + set file_re [string_to_regexp $::binfile] + set suffix "using automatic value \"$file_re\"" + } + gdb_test "show remote exec-file" \ + "The remote exec-file is unset, ${suffix}\\." \ + "check remote exec-file is unset" + + 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" + + # Check GDB reflect the value we just set. + set file_re [string_to_regexp $target_exec] + gdb_test "show remote exec-file" \ + "The remote exec-file is \"$file_re\"\\." \ + "check remote exec-file after set" + } + + 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 + } + } + } + + 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_lines "info os processes" "get process list" \ + "^pid +user +command.*\r\n1 +root +\[/a-z\]*(init|systemd|bash)" + } + } + + gdb_test "kill" "" "kill" "Kill the program being debugged. .y or n. " "y" + + 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.47.1