diff options
author | Chaoren Lin <chaorenl@google.com> | 2015-04-27 23:20:30 +0000 |
---|---|---|
committer | Chaoren Lin <chaorenl@google.com> | 2015-04-27 23:20:30 +0000 |
commit | 368c9f6e9b050897dcae4cb84e1cd54e91287a24 (patch) | |
tree | 2aae3487d1323eb23559b5a9c4cdaf89c12c0e28 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | |
parent | 7832e0a2f05c07101f8b320220a1165b2e148e4d (diff) | |
download | llvm-368c9f6e9b050897dcae4cb84e1cd54e91287a24.zip llvm-368c9f6e9b050897dcae4cb84e1cd54e91287a24.tar.gz llvm-368c9f6e9b050897dcae4cb84e1cd54e91287a24.tar.bz2 |
Add an unnamed pipe fail-safe to launching lldb-gdbserver.
Summary:
Currently, launching lldb-gdbserver from platform on Android requires root for
mkfifo() and an explicit TMPDIR variable. This should remove both requirements.
Test Plan: Successfully launched lldb-gdbserver on a non-rooted Android device.
Reviewers: tberghammer, vharron, clayborg
Reviewed By: clayborg
Subscribers: tberghammer, lldb-commits
Differential Revision: http://reviews.llvm.org/D9307
llvm-svn: 235940
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 105 |
1 files changed, 67 insertions, 38 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 0470665..a6d9f95 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -770,7 +770,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, } llvm::SmallString<PATH_MAX> named_pipe_path; - Pipe port_named_pipe; + Pipe port_pipe; bool listen = false; if (host_and_port[0]) @@ -783,11 +783,33 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, { // Binding to port zero, we need to figure out what port it ends up // using using a named pipe... - error = port_named_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path); - if (error.Fail()) - return error; - debugserver_args.AppendArgument("--named-pipe"); - debugserver_args.AppendArgument(named_pipe_path.c_str()); + error = port_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path); + if (error.Success()) + { + debugserver_args.AppendArgument("--named-pipe"); + debugserver_args.AppendArgument(named_pipe_path.c_str()); + } + else + { + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "named pipe creation failed: %s", + __FUNCTION__, error.AsCString()); + // let's try an unnamed pipe + error = port_pipe.CreateNew(true); + if (error.Fail()) + { + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "unnamed pipe creation failed: %s", + __FUNCTION__, error.AsCString()); + return error; + } + int write_fd = port_pipe.GetWriteFileDescriptor(); + debugserver_args.AppendArgument("--pipe"); + debugserver_args.AppendArgument(std::to_string(write_fd).c_str()); + launch_info.AppendCloseFileAction(port_pipe.GetReadFileDescriptor()); + } } else { @@ -869,50 +891,57 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, { if (named_pipe_path.size() > 0) { - error = port_named_pipe.OpenAsReader(named_pipe_path, false); + error = port_pipe.OpenAsReader(named_pipe_path, false); + if (error.Fail()) + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "failed to open named pipe %s for reading: %s", + __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); + } + + if (port_pipe.CanWrite()) + port_pipe.CloseWriteFileDescriptor(); + if (port_pipe.CanRead()) + { + char port_cstr[256]; + port_cstr[0] = '\0'; + size_t num_bytes = sizeof(port_cstr); + // Read port from pipe with 10 second timeout. + error = port_pipe.ReadWithTimeout(port_cstr, num_bytes, + std::chrono::seconds{10}, num_bytes); if (error.Success()) { - char port_cstr[256]; - port_cstr[0] = '\0'; - size_t num_bytes = sizeof(port_cstr); - // Read port from pipe with 10 second timeout. - error = port_named_pipe.ReadWithTimeout(port_cstr, num_bytes, std::chrono::microseconds(10 * 1000000), num_bytes); - if (error.Success()) - { - assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); - out_port = StringConvert::ToUInt32(port_cstr, 0); - if (log) - log->Printf("GDBRemoteCommunication::%s() debugserver listens %u port", __FUNCTION__, out_port); - } - else - { - if (log) - log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); - - } - port_named_pipe.Close(); + assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); + out_port = StringConvert::ToUInt32(port_cstr, 0); + if (log) + log->Printf("GDBRemoteCommunication::%s() " + "debugserver listens %u port", + __FUNCTION__, out_port); } else { if (log) - log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); + log->Printf("GDBRemoteCommunication::%s() " + "failed to read a port value from pipe %s: %s", + __FUNCTION__, named_pipe_path.c_str(), error.AsCString()); + } - const auto err = port_named_pipe.Delete(named_pipe_path); + port_pipe.Close(); + } + + if (named_pipe_path.size() > 0) + { + const auto err = port_pipe.Delete(named_pipe_path); if (err.Fail()) { if (log) - log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), err.AsCString()); + log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", + __FUNCTION__, named_pipe_path.c_str(), err.AsCString()); } } - else if (listen) - { - - } - else - { - // Make sure we actually connect with the debugserver... - JoinListenThread(); - } + + // Make sure we actually connect with the debugserver... + JoinListenThread(); } } else |