summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp50
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h10
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp25
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h10
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp32
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp17
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp37
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h5
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp169
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h17
12 files changed, 320 insertions, 66 deletions
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 9a55be64e4d..3d91dd6b7a3 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -223,3 +223,53 @@ PlatformAndroidRemoteGDBServer::MakeConnectURL(const lldb::pid_t pid,
return error;
}
+
+lldb::ProcessSP
+PlatformAndroidRemoteGDBServer::ConnectProcess(const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error)
+{
+ // We don't have the pid of the remote gdbserver when it isn't started by us but we still want
+ // to store the list of port forwards we set up in our port forward map. Generate a fake pid for
+ // these cases what won't collide with any other valid pid on android.
+ static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
+
+ int remote_port;
+ std::string scheme, host, path;
+ if (!UriParser::Parse(connect_url, scheme, host, remote_port, path))
+ {
+ error.SetErrorStringWithFormat("Invalid URL: %s", connect_url);
+ return nullptr;
+ }
+
+ std::string new_connect_url;
+ error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
+ (remote_port < 0) ? 0 : remote_port,
+ path.c_str(),
+ new_connect_url);
+ if (error.Fail())
+ return nullptr;
+
+ return PlatformRemoteGDBServer::ConnectProcess(new_connect_url.c_str(),
+ plugin_name,
+ debugger,
+ target,
+ error);
+}
+
+size_t
+PlatformAndroidRemoteGDBServer::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
+{
+ std::vector<std::string> connection_urls;
+ GetPendingGdbServerList(connection_urls);
+
+ for (size_t i = 0; i < connection_urls.size(); ++i)
+ {
+ ConnectProcess(connection_urls[i].c_str(), nullptr, debugger, nullptr, error);
+ if (error.Fail())
+ return i; // We already connected to i process succsessfully
+ }
+ return connection_urls.size();
+}
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index 84530ade935..3d2653812de 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -39,6 +39,16 @@ public:
Error
DisconnectRemote () override;
+ lldb::ProcessSP
+ ConnectProcess (const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
+
+ size_t
+ ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
+
protected:
std::string m_device_id;
std::map<lldb::pid_t, uint16_t> m_port_forwards;
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 6983e3d46de..c7564655a11 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -986,6 +986,23 @@ PlatformPOSIX::UnloadImage (lldb_private::Process* process, uint32_t image_token
process->ResetImageToken(image_token);
}
return Error();
+}
+
+lldb::ProcessSP
+PlatformPOSIX::ConnectProcess (const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error)
+{
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->ConnectProcess(connect_url,
+ plugin_name,
+ debugger,
+ target,
+ error);
+
+ return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, error);
}
const char*
@@ -998,3 +1015,11 @@ PlatformPOSIX::GetLibdlFunctionDeclarations() const
extern "C" char* dlerror(void);
)";
}
+
+size_t
+PlatformPOSIX::ConnectToWaitingProcesses(Debugger& debugger, Error& error)
+{
+ if (m_remote_platform_sp)
+ return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
+ return Platform::ConnectToWaitingProcesses(debugger, error);
+}
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 6dabeed0b18..60f6207d140 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -181,6 +181,16 @@ public:
lldb_private::Error
UnloadImage (lldb_private::Process* process, uint32_t image_token) override;
+ lldb::ProcessSP
+ ConnectProcess (const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
+
+ size_t
+ ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_private::Error& error) override;
+
protected:
std::unique_ptr<lldb_private::OptionGroupOptions> m_options;
lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index ea83027bfe5..f16ea017676 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
@@ -984,3 +985,34 @@ PlatformRemoteGDBServer::MakeUrl(const char* scheme,
result.Write(path, strlen(path));
return result.GetString();
}
+
+lldb::ProcessSP
+PlatformRemoteGDBServer::ConnectProcess(const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error)
+{
+ if (!IsRemote() || !IsConnected())
+ {
+ error.SetErrorString("Not connected to remote gdb server");
+ return nullptr;
+ }
+ return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, error);
+}
+
+size_t
+PlatformRemoteGDBServer::GetPendingGdbServerList(std::vector<std::string>& connection_urls)
+{
+ std::vector<std::pair<uint16_t, std::string>> remote_servers;
+ m_gdb_client.QueryGDBServer(remote_servers);
+ for (const auto& gdbserver : remote_servers)
+ {
+ const char* socket_name_cstr = gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
+ connection_urls.emplace_back(MakeGdbServerUrl(m_platform_scheme,
+ m_platform_hostname,
+ gdbserver.first,
+ socket_name_cstr));
+ }
+ return connection_urls.size();
+}
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index ffba509bbfb..61136f1185e 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -217,6 +217,16 @@ public:
const lldb::UnixSignalsSP &
GetRemoteUnixSignals() override;
+ lldb::ProcessSP
+ ConnectProcess (const char* connect_url,
+ const char* plugin_name,
+ lldb_private::Debugger &debugger,
+ lldb_private::Target *target,
+ lldb_private::Error &error) override;
+
+ virtual size_t
+ GetPendingGdbServerList(std::vector<std::string>& connection_urls);
+
protected:
process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
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/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index ea95298dd5c..2ea1f206008 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1115,7 +1115,8 @@ Error
GDBRemoteCommunication::StartDebugserverProcess (const char *url,
Platform *platform,
ProcessLaunchInfo &launch_info,
- uint16_t *port)
+ uint16_t *port,
+ const Args& inferior_args)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
@@ -1328,6 +1329,20 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
}
} while (has_env_var);
+ if (inferior_args.GetArgumentCount() > 0)
+ {
+ debugserver_args.AppendArgument ("--");
+ debugserver_args.AppendArguments (inferior_args);
+ }
+
+ // Copy the current environment to the gdbserver/debugserver instance
+ StringList env;
+ if (Host::GetEnvironment(env))
+ {
+ for (size_t i = 0; i < env.GetSize(); ++i)
+ launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
+ }
+
// Close STDIN, STDOUT and STDERR.
launch_info.AppendCloseFileAction (STDIN_FILENO);
launch_info.AppendCloseFileAction (STDOUT_FILENO);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ccc8ef1b247..2a01bcec260 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -25,6 +25,7 @@
#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/TimeValue.h"
+#include "lldb/Interpreter/Args.h"
#include "Utility/StringExtractorGDBRemote.h"
@@ -168,7 +169,8 @@ public:
StartDebugserverProcess(const char *url,
Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
ProcessLaunchInfo &launch_info,
- uint16_t *port);
+ uint16_t *port,
+ const Args& inferior_args = Args());
void
DumpHistory(Stream &strm);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 7b193f0bffb..5c7f6caca51 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3383,6 +3383,43 @@ GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostnam
return false;
}
+size_t
+GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
+{
+ connection_urls.clear();
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
+ return 0;
+
+ StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
+ if (!data)
+ return 0;
+
+ StructuredData::Array* array = data->GetAsArray();
+ if (!array)
+ return 0;
+
+ for (size_t i = 0, count = array->GetSize(); i < count; ++i)
+ {
+ StructuredData::Dictionary* element = nullptr;
+ if (!array->GetItemAtIndexAsDictionary(i, element))
+ continue;
+
+ uint16_t port = 0;
+ if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port")))
+ port = port_osp->GetIntegerValue(0);
+
+ std::string socket_name;
+ if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name")))
+ socket_name = socket_name_osp->GetStringValue();
+
+ if (port != 0 || !socket_name.empty())
+ connection_urls.emplace_back(port, socket_name);
+ }
+ return connection_urls.size();
+}
+
bool
GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
{
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 2c41d199ca5..d2df214d0db 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -119,7 +119,10 @@ public:
lldb::pid_t &pid,
uint16_t &port,
std::string &socket_name);
-
+
+ size_t
+ QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls);
+
bool
KillSpawnedProcess (lldb::pid_t pid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 19a29b4654a..022c558352b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -34,6 +34,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/JSON.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"
@@ -54,7 +55,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const
m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
m_platform_sp (Platform::GetHostPlatform ()),
m_port_map (),
- m_port_offset(0)
+ m_port_offset(0),
+ m_pending_gdb_server{ LLDB_INVALID_PROCESS_ID, 0, "" }
{
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
&GDBRemoteCommunicationServerPlatform::Handle_qC);
@@ -62,6 +64,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const
&GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
&GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
+ &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
&GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
@@ -90,38 +94,16 @@ GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform()
{
}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
+Error
+GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args& args,
+ std::string hostname,
+ lldb::pid_t& pid,
+ uint16_t& port,
+ std::string& socket_name)
{
-#ifdef _WIN32
- return SendErrorResponse(9);
-#else
- // Spawn a local debugserver as a platform so we can then attach or launch
- // a process...
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);
-
- // Sleep and wait a bit for debugserver to start to listen...
- ConnectionFileDescriptor file_conn;
- std::string hostname;
- // TODO: /tmp/ should not be hardcoded. User might want to override /tmp
- // with the TMPDIR environment variable
- packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
- std::string name;
- std::string value;
- uint16_t port = UINT16_MAX;
- while (packet.GetNameColonValue(name, value))
- {
- if (name.compare ("host") == 0)
- hostname.swap(value);
- else if (name.compare ("port") == 0)
- port = StringConvert::ToUInt32(value.c_str(), 0, 0);
- }
if (port == UINT16_MAX)
port = GetNextAvailablePort();
-
+
// Spawn a new thread to accept the port that gets bound after
// binding to port 0 (zero).
@@ -132,6 +114,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
ProcessLaunchInfo debugserver_launch_info;
if (hostname.empty())
hostname = "127.0.0.1";
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
@@ -148,11 +132,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
- std::string socket_name;
std::ostringstream url;
-
uint16_t* port_ptr = &port;
- url << m_socket_scheme << "://";
if (m_socket_protocol == Socket::ProtocolTcp)
url << platform_ip << ":" << port;
else
@@ -165,56 +146,108 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
Error error = StartDebugserverProcess (url.str().c_str(),
nullptr,
debugserver_launch_info,
- port_ptr);
-
- lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
-
+ port_ptr,
+ args);
- if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ pid = debugserver_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
{
Mutex::Locker locker (m_spawned_pids_mutex);
- m_spawned_pids.insert(debugserver_pid);
+ m_spawned_pids.insert(pid);
if (port > 0)
- AssociatePortWithProcess(port, debugserver_pid);
+ AssociatePortWithProcess(port, pid);
}
else
{
if (port > 0)
- FreePort (port);
+ FreePort(port);
}
+ return error;
+}
- if (error.Success())
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
+{
+#ifdef _WIN32
+ return SendErrorResponse(9);
+#else
+ // Spawn a local debugserver as a platform so we can then attach or launch
+ // a process...
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);
+
+ ConnectionFileDescriptor file_conn;
+ std::string hostname;
+ packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
+ std::string name;
+ std::string value;
+ uint16_t port = UINT16_MAX;
+ while (packet.GetNameColonValue(name, value))
+ {
+ if (name.compare ("host") == 0)
+ hostname.swap(value);
+ else if (name.compare ("port") == 0)
+ port = StringConvert::ToUInt32(value.c_str(), 0, 0);
+ }
+
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ std::string socket_name;
+ Error error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
+ if (error.Fail())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
+ return SendErrorResponse(9);
+ }
- StreamGDBRemote response;
- response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- if (!socket_name.empty())
- {
- response.PutCString("socket_name:");
- response.PutCStringAsRawHex8(socket_name.c_str());
- response.PutChar(';');
- }
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
- PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
- if (packet_result != PacketResult::Success)
- {
- if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
- ::kill (debugserver_pid, SIGINT);
- }
- return packet_result;
+ StreamGDBRemote response;
+ response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
+ if (!socket_name.empty())
+ {
+ response.PutCString("socket_name:");
+ response.PutCStringAsRawHex8(socket_name.c_str());
+ response.PutChar(';');
}
- else
+
+ PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
+ if (packet_result != PacketResult::Success)
{
- if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
+ if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ ::kill (debugserver_pid, SIGINT);
}
- return SendErrorResponse (9);
+ return packet_result;
#endif
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer (StringExtractorGDBRemote &packet)
+{
+ if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(4);
+
+ JSONObject::SP server_sp = std::make_shared<JSONObject>();
+ server_sp->SetObject("port", std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+ if (!m_pending_gdb_server.socket_name.empty())
+ server_sp->SetObject("socket_name",
+ std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+
+ JSONArray server_list;
+ server_list.AppendObject(server_sp);
+
+ StreamGDBRemote response;
+ server_list.Write(response);
+
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+ return SendPacketNoLock(escaped_response.GetData(), escaped_response.GetSize());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
@@ -553,7 +586,17 @@ GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix)
}
void
-GDBRemoteCommunicationServerPlatform::SetPortOffset (uint16_t port_offset)
+GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset)
{
m_port_offset = port_offset;
}
+
+void
+GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(lldb::pid_t pid,
+ uint16_t port,
+ const std::string& socket_name)
+{
+ m_pending_gdb_server.pid = pid;
+ m_pending_gdb_server.port = port;
+ m_pending_gdb_server.socket_name = socket_name;
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 6e8f5b06e16..1fe7207d2bc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -66,6 +66,19 @@ public:
void
SetPortOffset (uint16_t port_offset);
+ void
+ SetInferiorArguments (const lldb_private::Args& args);
+
+ Error
+ LaunchGDBServer(const lldb_private::Args& args,
+ std::string hostname,
+ lldb::pid_t& pid,
+ uint16_t& port,
+ std::string& socket_name);
+
+ void
+ SetPendingGdbServer(lldb::pid_t pid, uint16_t port, const std::string& socket_name);
+
protected:
const Socket::SocketProtocol m_socket_protocol;
const std::string m_socket_scheme;
@@ -75,11 +88,15 @@ protected:
PortMap m_port_map;
uint16_t m_port_offset;
+ struct { lldb::pid_t pid; uint16_t port; std::string socket_name; } m_pending_gdb_server;
PacketResult
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
PacketResult
+ Handle_qQueryGDBServer (StringExtractorGDBRemote &packet);
+
+ PacketResult
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
PacketResult
OpenPOWER on IntegriCloud