diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 118 |
1 files changed, 82 insertions, 36 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 1f4dd93..919fa54 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -17,15 +17,16 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" +#include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/TimeValue.h" #include "lldb/Target/Process.h" @@ -153,7 +154,6 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, m_history (512), m_send_acks (true), m_is_platform (is_platform), - m_listen_thread (LLDB_INVALID_HOST_THREAD), m_listen_url () { } @@ -227,9 +227,23 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; - size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); + const char *packet_data = packet.GetData(); + const size_t packet_length = packet.GetSize(); + size_t bytes_written = Write (packet_data, packet_length, status, NULL); if (log) { + size_t binary_start_offset = 0; + if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0) + { + const char *first_comma = strchr(packet_data, ','); + if (first_comma) + { + const char *second_comma = strchr(first_comma + 1, ','); + if (second_comma) + binary_start_offset = second_comma - packet_data + 1; + } + } + // If logging was just enabled and we have history, then dump out what // we have to the log so we get the historical context. The Dump() call that // logs all of the packet will set a boolean so that we don't dump this more @@ -237,13 +251,27 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le if (!m_history.DidDumpToLog ()) m_history.Dump (log); - log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData()); + if (binary_start_offset) + { + StreamString strm; + // Print non binary data header + strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data); + const uint8_t *p; + // Print binary data exactly as sent + for (p = (uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p) + strm.Printf("\\x%2.2x", *p); + // Print the checksum + strm.Printf("%*s", (int)3, p); + log->PutCString(strm.GetString().c_str()); + } + else + log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data); } - m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written); + m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written); - if (bytes_written == packet.GetSize()) + if (bytes_written == packet_length) { if (GetSendAcks ()) return GetAck (); @@ -253,7 +281,7 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le else { if (log) - log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); + log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data); } } return PacketResult::ErrorSendFailed; @@ -447,8 +475,8 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri } if (log) log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", - __FUNCTION__, idx, idx, m_bytes.c_str()); - m_bytes.erase(0, idx); + __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str()); + m_bytes.erase(0, idx - 1); } break; } @@ -606,7 +634,7 @@ Error GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) { Error error; - if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) + if (m_listen_thread.IsJoinable()) { error.SetErrorString("listen thread already running"); } @@ -619,7 +647,7 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) snprintf(listen_url, sizeof(listen_url), "listen://%i", port); m_listen_url = listen_url; SetConnection(new ConnectionFileDescriptor()); - m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error); + m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error); } return error; } @@ -627,11 +655,8 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) bool GDBRemoteCommunication::JoinListenThread () { - if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) - { - Host::ThreadJoin(m_listen_thread, NULL, NULL); - m_listen_thread = LLDB_INVALID_HOST_THREAD; - } + if (m_listen_thread.IsJoinable()) + m_listen_thread.Join(nullptr); return true; } @@ -738,6 +763,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, char named_pipe_path[PATH_MAX]; named_pipe_path[0] = '\0'; + Pipe port_named_pipe; bool listen = false; if (host_and_port[0]) @@ -763,15 +789,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, if (::mktemp (named_pipe_path)) { -#if defined(_WIN32) - if ( false ) -#else - if (::mkfifo(named_pipe_path, 0600) == 0) -#endif - { - debugserver_args.AppendArgument("--named-pipe"); - debugserver_args.AppendArgument(named_pipe_path); - } + error = port_named_pipe.CreateNew(named_pipe_path, false); + if (error.Fail()) + return error; + debugserver_args.AppendArgument("--named-pipe"); + debugserver_args.AppendArgument(named_pipe_path); } } else @@ -838,11 +860,15 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, } } while (has_env_var); - // Close STDIN, STDOUT and STDERR. We might need to redirect them - // to "/dev/null" if we run into any problems. + // Close STDIN, STDOUT and STDERR. launch_info.AppendCloseFileAction (STDIN_FILENO); launch_info.AppendCloseFileAction (STDOUT_FILENO); launch_info.AppendCloseFileAction (STDERR_FILENO); + + // Redirect STDIN, STDOUT and STDERR to "/dev/null". + launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); + launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); + launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); error = Host::LaunchProcess(launch_info); @@ -850,20 +876,40 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, { if (named_pipe_path[0]) { - File name_pipe_file; - error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead); + error = port_named_pipe.OpenAsReader(named_pipe_path, false); if (error.Success()) { char port_cstr[256]; port_cstr[0] = '\0'; size_t num_bytes = sizeof(port_cstr); - error = name_pipe_file.Read(port_cstr, num_bytes); - assert (error.Success()); - assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); - out_port = Args::StringToUInt32(port_cstr, 0); - name_pipe_file.Close(); + // 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 = Args::StringToUInt32(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, error.AsCString()); + + } + port_named_pipe.Close(); + } + else + { + if (log) + log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path, error.AsCString()); + } + const auto err = port_named_pipe.Delete(named_pipe_path); + if (err.Fail()) + { + if (log) + log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path, err.AsCString()); } - FileSystem::Unlink(named_pipe_path); } else if (listen) { |