diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -12,8 +12,9 @@ #include -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" #include "Plugins/Process/Utility/GDBRemoteSignals.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h" #include "lldb/Target/Platform.h" namespace lldb_private { @@ -164,6 +165,7 @@ protected: process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client; + process_gdb_remote::GDBRemoteCommunicationReplayServer m_gdb_replay_server; std::string m_platform_description; // After we connect we can get a more // complete description of what we are // connected to diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -288,40 +288,55 @@ "execute 'platform disconnect' to close the " "current connection", GetHostname()); + return error; + } + + if (args.GetArgumentCount() != 1) { + error.SetErrorString( + "\"platform connect\" takes a single argument: "); + return error; + } + + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + + int port; + llvm::StringRef scheme, hostname, pathname; + if (!UriParser::Parse(url, scheme, hostname, port, pathname)) + return Status("Invalid URL: %s", url); + + // We're going to reuse the hostname when we connect to the debugserver. + m_platform_scheme = std::string(scheme); + m_platform_hostname = std::string(hostname); + + m_gdb_client.SetConnection(std::make_unique()); + if (repro::Reproducer::Instance().IsReplaying()) { + error = m_gdb_replay_server.Connect(m_gdb_client); + if (error.Success()) + m_gdb_replay_server.StartAsyncThread(); } else { - if (args.GetArgumentCount() == 1) { - m_gdb_client.SetConnection(std::make_unique()); - // we're going to reuse the hostname when we connect to the debugserver - int port; - std::string path; - const char *url = args.GetArgumentAtIndex(0); - if (!url) - return Status("URL is null."); - llvm::StringRef scheme, hostname, pathname; - if (!UriParser::Parse(url, scheme, hostname, port, pathname)) - return Status("Invalid URL: %s", url); - m_platform_scheme = std::string(scheme); - m_platform_hostname = std::string(hostname); - path = std::string(pathname); - - const ConnectionStatus status = m_gdb_client.Connect(url, &error); - if (status == eConnectionStatusSuccess) { - if (m_gdb_client.HandshakeWithServer(&error)) { - m_gdb_client.GetHostInfo(); - // If a working directory was set prior to connecting, send it down - // now - if (m_working_dir) - m_gdb_client.SetWorkingDir(m_working_dir); - } else { - m_gdb_client.Disconnect(); - if (error.Success()) - error.SetErrorString("handshake failed"); - } - } - } else { - error.SetErrorString( - "\"platform connect\" takes a single argument: "); + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + repro::GDBRemoteProvider &provider = + g->GetOrCreate(); + m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder()); } + m_gdb_client.Connect(url, &error); + } + + if (error.Fail()) + return error; + + if (m_gdb_client.HandshakeWithServer(&error)) { + m_gdb_client.GetHostInfo(); + // If a working directory was set prior to connecting, send it down + // now. + if (m_working_dir) + m_gdb_client.SetWorkingDir(m_working_dir); + } else { + m_gdb_client.Disconnect(); + if (error.Success()) + error.SetErrorString("handshake failed"); } return error; }