Skip to content

Commit f80358f

Browse files
sasshkaMark Wielaard
authored andcommitted
server.c: handle qExecAndArgs remote protocol 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 together with GDB like this: ./vg-in-place --tool=memcheck --vgdb-error=0 /bin/ls -lh ~/build/gdb/gdb/gdb target remote | coregrind/vgdb We can now ask GDB to show the executable's arguments: (gdb) show args Argument list to give program being debugged when it is started is "-lh". or the executable's name: (gdb) show remote exec-file The remote exec-file is "/bin/ls".
1 parent 4e3a4a2 commit f80358f

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

coregrind/m_gdbserver/server.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,65 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
873873
return;
874874
}
875875

876+
/* Without argument, traditional remote protocol. */
877+
if (strcmp ("qExecAndArgs", arg_own_buf) == 0) {
878+
const HChar *exename = VG_(resolved_exename);
879+
880+
/* If we don't have an executable, return "U". */
881+
if (exename == NULL) {
882+
arg_own_buf[0] = 'U';
883+
arg_own_buf[1] = '\0';
884+
return;
885+
}
886+
887+
/* Build the response: "S;<hex-prog>;<hex-args>;"
888+
Need to hex-encode both the program name and arguments. */
889+
890+
/* First, encode the executable name. */
891+
char hex_exename[2 * VG_(strlen)(exename) + 1];
892+
hexify(hex_exename, exename, VG_(strlen)(exename));
893+
894+
/* Build the arguments string from VG_(args_for_client). */
895+
int num_args = VG_(sizeXA)(VG_(args_for_client));
896+
char *args_str = NULL;
897+
898+
if (num_args > 0) {
899+
int count = 0;
900+
for (int i = 0; i < num_args; i++) {
901+
HChar* arg = * (HChar**) VG_(indexXA)(VG_(args_for_client), i);
902+
count += VG_(strlen)(arg);
903+
}
904+
905+
/* Allocate space for args + spaces between them + null terminator. */
906+
int args_str_size = count + num_args;
907+
args_str = VG_(malloc)("handle_query.qExecAndArgs", args_str_size);
908+
char *p = args_str;
909+
910+
for (int i = 0; i < num_args; i++) {
911+
HChar* arg = * (HChar**) VG_(indexXA)(VG_(args_for_client), i);
912+
int num = VG_(strlen)(arg);
913+
VG_(memcpy)(p, arg, num);
914+
p += num;
915+
if (i < num_args - 1) {
916+
*p++ = ' '; /* Add space separator between arguments. */
917+
}
918+
}
919+
*p = '\0'; /* Null terminate the string. */
920+
921+
char hex_args_buf[2 * VG_(strlen)(args_str) + 1];
922+
hexify(hex_args_buf, args_str, VG_(strlen)(args_str));
923+
VG_(free)(args_str);
924+
925+
/* Build the full response. */
926+
VG_(sprintf)(arg_own_buf, "S;%s;%s;", hex_exename, hex_args_buf);
927+
} else {
928+
/* No arguments, just send program name with empty args. */
929+
VG_(sprintf)(arg_own_buf, "S;%s;;", hex_exename);
930+
}
931+
932+
return;
933+
}
934+
876935
if (strcmp ("qSymbol::", arg_own_buf) == 0) {
877936
/* We have no symbol to read. */
878937
write_ok (arg_own_buf);

0 commit comments

Comments
 (0)