From: Alexandra Hájková Date: Wed, 15 Oct 2025 10:02:03 +0000 (-0400) Subject: vgdb.c: Handle qExecAndArgs packet X-Git-Tag: VALGRIND_3_26_0~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1684ce8a93740396e773ab94dcb546e9ad79c4b6;p=thirdparty%2Fvalgrind.git 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 --git a/coregrind/vgdb.c b/coregrind/vgdb.c index dab425d68..cc0be240b 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);