https://sourceware.org/cgit/valgrind/commit/?id=1684ce8a93740396e773ab94dcb546e9ad79c4b6
commit 1684ce8a93740396e773ab94dcb546e9ad79c4b6
Author: Alexandra Hájková <aha...@re...>
Date: Wed Oct 15 06:02:03 2025 -0400
vgdb.c: Handle qExecAndArgs packet
New qExecAndArgs packet has been added recently to GDB's remote
protocol.
The new qExecAndArgs packet is sent from GDB, and gdbserver replies
with a packet that includes the executable filename and the arguments
string that were used for starting the initial inferior.
On the GDB side this information can be used to update GDB's state,
the 'show remote exec-file' will reflect how gdbserver was started,
and 'show args' will reflect the arguments used for starting the
inferior.
When running Valgrind from inside GDB, we can see that GDB actually
sends the packet to vgdb and vgdb is able to respond to it.
gdb -ex 'set debug remote on' \
-ex 'set remote exec-file /bin/ls' \
-ex 'set sysroot /' \
-ex 'target extended-remote | ~/valgrind/coregrind/vgdb --multi --vargs -q' \
/bin/ls
[remote] Sending packet: $qExecAndArgs#96
[remote] Packet received: U
[remote] packet_ok: Packet qExecAndArgs (fetch-exec-and-args) is supported
To be able to run Valgrind from inside GDB we currently have to set
remote exec-file and our goal is to avoid that to make running Valgrind
from GDB easier for the users. There's work on GDB side which should allow
us to avoid this soon.
When vgdb replies with 'U', it indicates that no executable has been set.
GDB sees that the executable that it has loaded is inside the sysroot
(which we set with 'set sysroot /'), then GDB knows that the remote and
GDB can see the same file. GDB will then automatically use the current
executable path as the remote exec-file value.
Diff:
---
coregrind/vgdb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c
index dab425d680..cc0be240bf 100644
--- a/coregrind/vgdb.c
+++ b/coregrind/vgdb.c
@@ -1418,6 +1418,7 @@ void do_multi_mode(int check_trials, int in_port)
#define QENVIRONMENTUNSET "QEnvironmentUnset"
#define QSETWORKINGDIR "QSetWorkingDir"
#define QTSTATUS "qTStatus"
+#define QEXECANDARGS "qExecAndArgs"
if (strncmp(QSUPPORTED, buf, strlen(QSUPPORTED)) == 0) {
DEBUG(1, "CASE %s\n", QSUPPORTED);
@@ -1669,6 +1670,10 @@ void do_multi_mode(int check_trials, int in_port)
DEBUG(1, "Got qfThreadInfo\n");
/* There are no threads yet, reply 'l' end of list. */
send_packet ("l", noackmode);
+ } else if (strcmp(QEXECANDARGS, buf) == 0) {
+ DEBUG(1, "Got qExecAndArgs\n");
+ /* We don't have any. */
+ send_packet ("U", noackmode);
} else if (buf[0] != '\0') {
// We didn't understand.
DEBUG(1, "Unknown packet received: '%s'\n", buf);
|