summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process')
-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
6 files changed, 183 insertions, 66 deletions
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