1 //===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "GDBRemoteCommunicationServerPlatform.h"
20 #include "llvm/Support/FileSystem.h"
21 #include "llvm/Support/Threading.h"
23 #include "lldb/Host/Config.h"
24 #include "lldb/Host/ConnectionFileDescriptor.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Host/HostInfo.h"
27 #include "lldb/Target/FileAction.h"
28 #include "lldb/Target/Platform.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/UnixSignals.h"
31 #include "lldb/Utility/JSON.h"
32 #include "lldb/Utility/Log.h"
33 #include "lldb/Utility/StreamGDBRemote.h"
34 #include "lldb/Utility/StreamString.h"
35 #include "lldb/Utility/StructuredData.h"
36 #include "lldb/Utility/UriParser.h"
38 #include "lldb/Utility/StringExtractorGDBRemote.h"
41 using namespace lldb_private;
42 using namespace lldb_private::process_gdb_remote;
44 //----------------------------------------------------------------------
45 // GDBRemoteCommunicationServerPlatform constructor
46 //----------------------------------------------------------------------
47 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
48 const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
49 : GDBRemoteCommunicationServerCommon("gdb-remote.server",
50 "gdb-remote.server.rx_packet"),
51 m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
52 m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
53 m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
54 m_pending_gdb_server.port = 0;
56 RegisterMemberFunctionHandler(
57 StringExtractorGDBRemote::eServerPacketType_qC,
58 &GDBRemoteCommunicationServerPlatform::Handle_qC);
59 RegisterMemberFunctionHandler(
60 StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
61 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
62 RegisterMemberFunctionHandler(
63 StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
64 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
65 RegisterMemberFunctionHandler(
66 StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
67 &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
68 RegisterMemberFunctionHandler(
69 StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
70 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
71 RegisterMemberFunctionHandler(
72 StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
73 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
74 RegisterMemberFunctionHandler(
75 StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
76 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
77 RegisterMemberFunctionHandler(
78 StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
79 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
81 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
82 [](StringExtractorGDBRemote packet, Status &error,
83 bool &interrupt, bool &quit) {
84 error.SetErrorString("interrupt received");
86 return PacketResult::Success;
90 //----------------------------------------------------------------------
92 //----------------------------------------------------------------------
93 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
95 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
96 const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
97 uint16_t &port, std::string &socket_name) {
98 if (port == UINT16_MAX)
99 port = GetNextAvailablePort();
101 // Spawn a new thread to accept the port that gets bound after binding to
104 // ignore the hostname send from the remote end, just use the ip address that
105 // we're currently communicating with as the hostname
107 // Spawn a debugserver and try to get the port it listens to.
108 ProcessLaunchInfo debugserver_launch_info;
109 if (hostname.empty())
110 hostname = "127.0.0.1";
112 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
114 log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
116 // Do not run in a new session so that it can not linger after the platform
118 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
119 debugserver_launch_info.SetMonitorProcessCallback(
120 std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
121 this, std::placeholders::_1),
124 llvm::StringRef platform_scheme;
125 llvm::StringRef platform_ip;
127 llvm::StringRef platform_path;
128 std::string platform_uri = GetConnection()->GetURI();
129 bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
130 platform_port, platform_path);
131 UNUSED_IF_ASSERT_DISABLED(ok);
134 std::ostringstream url;
135 // debugserver does not accept the URL scheme prefix.
136 #if !defined(__APPLE__)
137 url << m_socket_scheme << "://";
139 uint16_t *port_ptr = &port;
140 if (m_socket_protocol == Socket::ProtocolTcp)
141 url << platform_ip.str() << ":" << port;
143 socket_name = GetDomainSocketPath("gdbserver").GetPath();
148 Status error = StartDebugserverProcess(
149 url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
151 pid = debugserver_launch_info.GetProcessID();
152 if (pid != LLDB_INVALID_PROCESS_ID) {
153 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
154 m_spawned_pids.insert(pid);
156 AssociatePortWithProcess(port, pid);
164 GDBRemoteCommunication::PacketResult
165 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
166 StringExtractorGDBRemote &packet) {
167 // Spawn a local debugserver as a platform so we can then attach or launch a
170 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
172 log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
175 ConnectionFileDescriptor file_conn;
176 std::string hostname;
177 packet.SetFilePos(::strlen("qLaunchGDBServer;"));
178 llvm::StringRef name;
179 llvm::StringRef value;
180 uint16_t port = UINT16_MAX;
181 while (packet.GetNameColonValue(name, value)) {
182 if (name.equals("host"))
184 else if (name.equals("port"))
185 value.getAsInteger(0, port);
188 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
189 std::string socket_name;
191 LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
194 log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
196 __FUNCTION__, error.AsCString());
197 return SendErrorResponse(9);
201 log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
202 "launched successfully as pid %" PRIu64,
203 __FUNCTION__, debugserver_pid);
205 StreamGDBRemote response;
206 response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
207 port + m_port_offset);
208 if (!socket_name.empty()) {
209 response.PutCString("socket_name:");
210 response.PutCStringAsRawHex8(socket_name.c_str());
211 response.PutChar(';');
214 PacketResult packet_result = SendPacketNoLock(response.GetString());
215 if (packet_result != PacketResult::Success) {
216 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
217 Host::Kill(debugserver_pid, SIGINT);
219 return packet_result;
222 GDBRemoteCommunication::PacketResult
223 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
224 StringExtractorGDBRemote &packet) {
225 if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
226 return SendErrorResponse(4);
228 JSONObject::SP server_sp = std::make_shared<JSONObject>();
229 server_sp->SetObject("port",
230 std::make_shared<JSONNumber>(m_pending_gdb_server.port));
231 if (!m_pending_gdb_server.socket_name.empty())
232 server_sp->SetObject(
234 std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
236 JSONArray server_list;
237 server_list.AppendObject(server_sp);
239 StreamGDBRemote response;
240 server_list.Write(response);
242 StreamGDBRemote escaped_response;
243 escaped_response.PutEscapedBytes(response.GetString().data(),
245 return SendPacketNoLock(escaped_response.GetString());
248 GDBRemoteCommunication::PacketResult
249 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
250 StringExtractorGDBRemote &packet) {
251 packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
253 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
255 // verify that we know anything about this pid. Scope for locker
257 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
258 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
259 // not a pid we know about
260 return SendErrorResponse(10);
264 // go ahead and attempt to kill the spawned process
265 if (KillSpawnedProcess(pid))
266 return SendOKResponse();
268 return SendErrorResponse(11);
271 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
272 // make sure we know about this process
274 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
275 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
279 // first try a SIGTERM (standard kill)
280 Host::Kill(pid, SIGTERM);
282 // check if that worked
283 for (size_t i = 0; i < 10; ++i) {
285 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
286 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
294 // check one more time after the final usleep
296 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
297 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
301 // the launched process still lives. Now try killing it again, this time
302 // with an unblockable signal.
303 Host::Kill(pid, SIGKILL);
305 for (size_t i = 0; i < 10; ++i) {
307 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
308 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
316 // check one more time after the final usleep Scope for locker
318 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
319 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
323 // no luck - the process still lives
327 GDBRemoteCommunication::PacketResult
328 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
329 StringExtractorGDBRemote &packet) {
330 lldb::pid_t pid = m_process_launch_info.GetProcessID();
331 m_process_launch_info.Clear();
333 if (pid == LLDB_INVALID_PROCESS_ID)
334 return SendErrorResponse(1);
336 ProcessInstanceInfo proc_info;
337 if (!Host::GetProcessInfo(pid, proc_info))
338 return SendErrorResponse(1);
340 StreamString response;
341 CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
342 return SendPacketNoLock(response.GetString());
345 GDBRemoteCommunication::PacketResult
346 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
347 StringExtractorGDBRemote &packet) {
349 llvm::SmallString<64> cwd;
350 if (std::error_code ec = llvm::sys::fs::current_path(cwd))
351 return SendErrorResponse(ec.value());
353 StreamString response;
354 response.PutBytesAsRawHex8(cwd.data(), cwd.size());
355 return SendPacketNoLock(response.GetString());
358 GDBRemoteCommunication::PacketResult
359 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
360 StringExtractorGDBRemote &packet) {
361 packet.SetFilePos(::strlen("QSetWorkingDir:"));
363 packet.GetHexByteString(path);
365 if (std::error_code ec = llvm::sys::fs::set_current_path(path))
366 return SendErrorResponse(ec.value());
367 return SendOKResponse();
370 GDBRemoteCommunication::PacketResult
371 GDBRemoteCommunicationServerPlatform::Handle_qC(
372 StringExtractorGDBRemote &packet) {
373 // NOTE: lldb should now be using qProcessInfo for process IDs. This path
375 // should not be used. It is reporting process id instead of thread id. The
376 // correct answer doesn't seem to make much sense for lldb-platform.
377 // CONSIDER: flip to "unsupported".
378 lldb::pid_t pid = m_process_launch_info.GetProcessID();
380 StreamString response;
381 response.Printf("QC%" PRIx64, pid);
383 // If we launch a process and this GDB server is acting as a platform, then
384 // we need to clear the process launch state so we can start launching
385 // another process. In order to launch a process a bunch or packets need to
386 // be sent: environment packets, working directory, disable ASLR, and many
387 // more settings. When we launch a process we then need to know when to clear
388 // this information. Currently we are selecting the 'qC' packet as that
389 // packet which seems to make the most sense.
390 if (pid != LLDB_INVALID_PROCESS_ID) {
391 m_process_launch_info.Clear();
394 return SendPacketNoLock(response.GetString());
397 GDBRemoteCommunication::PacketResult
398 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
399 StringExtractorGDBRemote &packet) {
400 StructuredData::Array signal_array;
402 const auto &signals = Host::GetUnixSignals();
403 for (auto signo = signals->GetFirstSignalNumber();
404 signo != LLDB_INVALID_SIGNAL_NUMBER;
405 signo = signals->GetNextSignalNumber(signo)) {
406 auto dictionary = std::make_shared<StructuredData::Dictionary>();
408 dictionary->AddIntegerItem("signo", signo);
409 dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
411 bool suppress, stop, notify;
412 signals->GetSignalInfo(signo, suppress, stop, notify);
413 dictionary->AddBooleanItem("suppress", suppress);
414 dictionary->AddBooleanItem("stop", stop);
415 dictionary->AddBooleanItem("notify", notify);
417 signal_array.Push(dictionary);
420 StreamString response;
421 signal_array.Dump(response);
422 return SendPacketNoLock(response.GetString());
425 bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
427 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
428 FreePortForProcess(pid);
429 m_spawned_pids.erase(pid);
433 Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
434 if (!m_process_launch_info.GetArguments().GetArgumentCount())
435 return Status("%s: no process command line specified to launch",
438 // specify the process monitor if not already set. This should generally be
439 // what happens since we need to reap started processes.
440 if (!m_process_launch_info.GetMonitorProcessCallback())
441 m_process_launch_info.SetMonitorProcessCallback(
443 &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
444 this, std::placeholders::_1),
447 Status error = Host::LaunchProcess(m_process_launch_info);
448 if (!error.Success()) {
449 fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
450 m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
454 printf("Launched '%s' as process %" PRIu64 "...\n",
455 m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
456 m_process_launch_info.GetProcessID());
458 // add to list of spawned processes. On an lldb-gdbserver, we would expect
459 // there to be only one.
460 const auto pid = m_process_launch_info.GetProcessID();
461 if (pid != LLDB_INVALID_PROCESS_ID) {
462 // add to spawned pids
463 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
464 m_spawned_pids.insert(pid);
470 void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
471 m_port_map = port_map;
474 uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
475 if (m_port_map.empty())
476 return 0; // Bind to port zero and get a port, we didn't have any
479 for (auto &pair : m_port_map) {
480 if (pair.second == LLDB_INVALID_PROCESS_ID) {
481 pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
488 bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
489 uint16_t port, lldb::pid_t pid) {
490 PortMap::iterator pos = m_port_map.find(port);
491 if (pos != m_port_map.end()) {
498 bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
499 PortMap::iterator pos = m_port_map.find(port);
500 if (pos != m_port_map.end()) {
501 pos->second = LLDB_INVALID_PROCESS_ID;
507 bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
508 if (!m_port_map.empty()) {
509 for (auto &pair : m_port_map) {
510 if (pair.second == pid) {
511 pair.second = LLDB_INVALID_PROCESS_ID;
519 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
520 static FileSpec g_domainsocket_dir;
521 static llvm::once_flag g_once_flag;
523 llvm::call_once(g_once_flag, []() {
524 const char *domainsocket_dir_env =
525 ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
526 if (domainsocket_dir_env != nullptr)
527 g_domainsocket_dir = FileSpec(domainsocket_dir_env);
529 g_domainsocket_dir = HostInfo::GetProcessTempDir();
532 return g_domainsocket_dir;
536 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
537 llvm::SmallString<128> socket_path;
538 llvm::SmallString<128> socket_name(
539 (llvm::StringRef(prefix) + ".%%%%%%").str());
541 FileSpec socket_path_spec(GetDomainSocketDir());
542 socket_path_spec.AppendPathComponent(socket_name.c_str());
544 llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
545 return FileSpec(socket_path.c_str());
548 void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
549 m_port_offset = port_offset;
552 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
553 lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
554 m_pending_gdb_server.pid = pid;
555 m_pending_gdb_server.port = port;
556 m_pending_gdb_server.socket_name = socket_name;