diff options
author | Sergio Durigan Junior <sergiodj@redhat.com> | 2017-09-20 19:15:40 -0400 |
---|---|---|
committer | Sergio Durigan Junior <sergiodj@redhat.com> | 2017-10-04 02:01:45 -0400 |
commit | bc3b087de2401c65c02730d346e8bea4dc0504ae (patch) | |
tree | 49dff0f07ac85554669e8f7d807a4527743e7ab5 /gdb/gdbserver | |
parent | d092c5a2465ece3435131ae6fef1ccb6e70986cb (diff) | |
download | gdb-bc3b087de2401c65c02730d346e8bea4dc0504ae.zip gdb-bc3b087de2401c65c02730d346e8bea4dc0504ae.tar.gz gdb-bc3b087de2401c65c02730d346e8bea4dc0504ae.tar.bz2 |
Extend "set cwd" to work on gdbserver
This is the "natural" extension necessary for the "set cwd" command
(and the whole "set the inferior's cwd" logic) to work on gdbserver.
The idea here is to have a new remote packet, QSetWorkingDir (name
adopted from LLDB's extension to the RSP, as can be seen at
<https://raw.githubusercontent.com/llvm-mirror/lldb/master/docs/lldb-gdb-remote.txt>),
which sends an hex-encoded string representing the working directory
that the remote inferior will use. There is a slight difference from
the packet proposed by LLDB: GDB's version will accept empty
arguments, meaning that the user wants to clear the previously set
working directory for the inferior (i.e., "set cwd" without arguments
on GDB).
For UNIX-like targets this feature is already implemented on
nat/fork-inferior.c, and all gdbserver has to do is to basically
implement "set_inferior_cwd" and call it whenever such packet arrives.
For other targets, like Windows, it is possible to use the existing
"get_inferior_cwd" function and do the necessary steps to make sure
that the inferior will use the specified working directory.
Aside from that, the patch consists basically of updates to the
testcase (making it available on remote targets) and the
documentation.
No regressions found.
gdb/ChangeLog:
2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com>
* NEWS (Changes since GDB 8.0): Add entry about new
'set-cwd-on-gdbserver' feature.
(New remote packets): Add entry for QSetWorkingDir.
* common/common-inferior.h (set_inferior_cwd): New prototype.
* infcmd.c (set_inferior_cwd): Remove "static".
(show_cwd_command): Expand text to include remote debugging.
* remote.c: Add PACKET_QSetWorkingDir.
(remote_protocol_features) <QSetWorkingDir>: New entry for
PACKET_QSetWorkingDir.
(extended_remote_set_inferior_cwd): New function.
(extended_remote_create_inferior): Call
"extended_remote_set_inferior_cwd".
(_initialize_remote): Call "add_packet_config_cmd" for
QSetWorkingDir.
gdb/gdbserver/ChangeLog:
2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com>
* inferiors.c (set_inferior_cwd): New function.
* server.c (handle_general_set): Handle QSetWorkingDir packet.
(handle_query): Inform that QSetWorkingDir is supported.
* win32-low.c (create_process): Pass the inferior's cwd to
CreateProcess.
gdb/testsuite/ChangeLog:
2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com>
* gdb.base/set-cwd.exp: Make it available on
native-extended-gdbserver.
gdb/doc/ChangeLog:
2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com>
* gdb.texinfo (Starting your Program) <The working directory.>:
Mention remote debugging.
(Working Directory) <Your Program's Working Directory>:
Likewise.
(Connecting) <Remote Packet>: Add "set-working-dir"
and "QSetWorkingDir" to the table.
(Remote Protocol) <QSetWorkingDir>: New item, explaining the
packet.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/gdbserver/inferiors.c | 12 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 32 | ||||
-rw-r--r-- | gdb/gdbserver/win32-low.c | 22 |
4 files changed, 70 insertions, 4 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 25d527b..0bdeaba 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,13 @@ 2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com> + * inferiors.c (set_inferior_cwd): New function. + * server.c (handle_general_set): Handle QSetWorkingDir packet. + (handle_query): Inform that QSetWorkingDir is supported. + * win32-low.c (create_process): Pass the inferior's cwd to + CreateProcess. + +2017-10-04 Sergio Durigan Junior <sergiodj@redhat.com> + * inferiors.c (current_inferior_cwd): New global variable. (get_inferior_cwd): New function. * inferiors.h (struct process_info) <cwd>: New field. diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index 57d9956..154c167 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -456,3 +456,15 @@ get_inferior_cwd () { return current_inferior_cwd; } + +/* See common/common-inferior.h. */ + +void +set_inferior_cwd (const char *cwd) +{ + xfree ((void *) current_inferior_cwd); + if (cwd != NULL) + current_inferior_cwd = xstrdup (cwd); + else + current_inferior_cwd = NULL; +} diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index c4f1e8d..a959735 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -869,6 +869,35 @@ handle_general_set (char *own_buf) return; } + if (startswith (own_buf, "QSetWorkingDir:")) + { + const char *p = own_buf + strlen ("QSetWorkingDir:"); + + if (*p != '\0') + { + std::string path = hex2str (p); + + set_inferior_cwd (path.c_str ()); + + if (remote_debug) + debug_printf (_("[Set the inferior's current directory to %s]\n"), + path.c_str ()); + } + else + { + /* An empty argument means that we should clear out any + previously set cwd for the inferior. */ + set_inferior_cwd (NULL); + + if (remote_debug) + debug_printf (_("\ +[Unset the inferior's current directory; will use gdbserver's cwd]\n")); + } + write_ok (own_buf); + + return; + } + /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; @@ -2351,7 +2380,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) sprintf (own_buf, "PacketSize=%x;QPassSignals+;QProgramSignals+;" "QStartupWithShell+;QEnvironmentHexEncoded+;" - "QEnvironmentReset+;QEnvironmentUnset+", + "QEnvironmentReset+;QEnvironmentUnset+;" + "QSetWorkingDir+", PBUFSIZ - 1); if (target_supports_catch_syscall ()) diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index cc84d15..c11926f 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -32,6 +32,7 @@ #include <tlhelp32.h> #include <psapi.h> #include <process.h> +#include "gdb_tilde_expand.h" #ifndef USE_WIN32API #include <sys/cygwin.h> @@ -562,10 +563,12 @@ static BOOL create_process (const char *program, char *args, DWORD flags, PROCESS_INFORMATION *pi) { + const char *inferior_cwd = get_inferior_cwd (); + std::string expanded_infcwd = gdb_tilde_expand (inferior_cwd); BOOL ret; #ifdef _WIN32_WCE - wchar_t *p, *wprogram, *wargs; + wchar_t *p, *wprogram, *wargs, *wcwd = NULL; size_t argslen; wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t)); @@ -579,6 +582,19 @@ create_process (const char *program, char *args, wargs = alloca ((argslen + 1) * sizeof (wchar_t)); mbstowcs (wargs, args, argslen + 1); + if (inferior_cwd != NULL) + { + std::replace (expanded_infcwd.begin (), expanded_infcwd.end (), + '/', '\\'); + wcwd = alloca ((expanded_infcwd.size () + 1) * sizeof (wchar_t)); + if (mbstowcs (wcwd, expanded_infcwd.c_str (), + expanded_infcwd.size () + 1) == NULL) + { + error (_("\ +Could not convert the expanded inferior cwd to wide-char.")); + } + } + ret = CreateProcessW (wprogram, /* image name */ wargs, /* command line */ NULL, /* security, not supported */ @@ -586,7 +602,7 @@ create_process (const char *program, char *args, FALSE, /* inherit handles, not supported */ flags, /* start flags */ NULL, /* environment, not supported */ - NULL, /* current directory, not supported */ + wcwd, /* current directory */ NULL, /* start info, not supported */ pi); /* proc info */ #else @@ -599,7 +615,7 @@ create_process (const char *program, char *args, TRUE, /* inherit handles */ flags, /* start flags */ NULL, /* environment */ - NULL, /* current directory */ + expanded_infcwd.c_str (), /* current directory */ &si, /* start info */ pi); /* proc info */ #endif |