summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Platform/gdb-server
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Platform/gdb-server')
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp96
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h14
2 files changed, 66 insertions, 44 deletions
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 1e62ddfe94fdb..21bf7f4ac46d3 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformRemoteGDBServer.cpp -----------------------------*- C++ -*-===//
+//===-- PlatformRemoteGDBServer.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -35,6 +35,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_gdb_server;
+LLDB_PLUGIN_DEFINE_ADV(PlatformRemoteGDBServer, PlatformGDB)
+
static bool g_initialized = false;
void PlatformRemoteGDBServer::Initialize() {
@@ -286,40 +288,55 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
"execute 'platform disconnect' to close the "
"current connection",
GetHostname());
+ return error;
+ }
+
+ if (args.GetArgumentCount() != 1) {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
+ 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<ConnectionFileDescriptor>());
+ 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(new ConnectionFileDescriptor());
- // 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 = scheme;
- m_platform_hostname = hostname;
- path = 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: <connect-url>");
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ repro::GDBRemoteProvider &provider =
+ g->GetOrCreate<repro::GDBRemoteProvider>();
+ 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;
}
@@ -486,10 +503,10 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
"gdb-remote", nullptr);
if (process_sp) {
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
// Retry the connect remote one time...
if (error.Fail())
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
if (error.Success())
error = process_sp->Launch(launch_info);
else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) {
@@ -572,7 +589,7 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
target->CreateProcess(attach_info.GetListenerForProcess(debugger),
"gdb-remote", nullptr);
if (process_sp) {
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
if (error.Success()) {
ListenerSP listener_sp = attach_info.GetHijackListener();
if (listener_sp)
@@ -725,7 +742,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
response.GetResponseType() != response.eResponse)
return m_remote_signals_sp;
- auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ auto object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (!object_sp || !object_sp->IsValid())
return m_remote_signals_sp;
@@ -772,7 +790,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
std::string description{""};
object_sp = dict->GetValueForKey("description");
if (object_sp && object_sp->IsValid())
- description = object_sp->GetStringValue();
+ description = std::string(object_sp->GetStringValue());
remote_signals_sp->AddSignal(signo, name.str().c_str(), suppress, stop,
notify, description.c_str());
@@ -811,7 +829,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
result.Printf(":%u", port);
if (path)
result.Write(path, strlen(path));
- return result.GetString();
+ return std::string(result.GetString());
}
lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess(
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 13edcbab9f591..0602be1fa377a 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformRemoteGDBServer_h_
-#define liblldb_PlatformRemoteGDBServer_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
#include <string>
-#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 @@ public:
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
@@ -192,10 +194,12 @@ private:
llvm::Optional<std::string> DoGetUserName(UserIDResolver::id_t uid) override;
llvm::Optional<std::string> DoGetGroupName(UserIDResolver::id_t uid) override;
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteGDBServer);
+ PlatformRemoteGDBServer(const PlatformRemoteGDBServer &) = delete;
+ const PlatformRemoteGDBServer &
+ operator=(const PlatformRemoteGDBServer &) = delete;
};
} // namespace platform_gdb_server
} // namespace lldb_private
-#endif // liblldb_PlatformRemoteGDBServer_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H