summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
diff options
context:
space:
mode:
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.cpp118
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)
{
OpenPOWER on IntegriCloud