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"
21 // Other libraries and framework includes
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/Threading.h"
25 #include "lldb/Host/Config.h"
26 #include "lldb/Host/ConnectionFileDescriptor.h"
27 #include "lldb/Host/Host.h"
28 #include "lldb/Host/HostInfo.h"
29 #include "lldb/Target/FileAction.h"
30 #include "lldb/Target/Platform.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/UnixSignals.h"
33 #include "lldb/Utility/JSON.h"
34 #include "lldb/Utility/Log.h"
35 #include "lldb/Utility/StreamGDBRemote.h"
36 #include "lldb/Utility/StreamString.h"
37 #include "lldb/Utility/StructuredData.h"
38 #include "lldb/Utility/UriParser.h"
41 #include "Utility/StringExtractorGDBRemote.h"
44 using namespace lldb_private;
45 using namespace lldb_private::process_gdb_remote;
47 //----------------------------------------------------------------------
48 // GDBRemoteCommunicationServerPlatform constructor
49 //----------------------------------------------------------------------
50 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
51 const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
52 : GDBRemoteCommunicationServerCommon("gdb-remote.server",
53 "gdb-remote.server.rx_packet"),
54 m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
55 m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
56 m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
57 m_pending_gdb_server.port = 0;
59 RegisterMemberFunctionHandler(
60 StringExtractorGDBRemote::eServerPacketType_qC,
61 &GDBRemoteCommunicationServerPlatform::Handle_qC);
62 RegisterMemberFunctionHandler(
63 StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
64 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
65 RegisterMemberFunctionHandler(
66 StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
67 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
68 RegisterMemberFunctionHandler(
69 StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
70 &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
71 RegisterMemberFunctionHandler(
72 StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
73 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
74 RegisterMemberFunctionHandler(
75 StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
76 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
77 RegisterMemberFunctionHandler(
78 StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
79 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
80 RegisterMemberFunctionHandler(
81 StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
82 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
84 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
85 [](StringExtractorGDBRemote packet, Status &error,
86 bool &interrupt, bool &quit) {
87 error.SetErrorString("interrupt received");
89 return PacketResult::Success;
93 //----------------------------------------------------------------------
95 //----------------------------------------------------------------------
96 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
98 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
99 const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
100 uint16_t &port, std::string &socket_name) {
101 if (port == UINT16_MAX)
102 port = GetNextAvailablePort();
104 // Spawn a new thread to accept the port that gets bound after
105 // binding to port 0 (zero).
107 // ignore the hostname send from the remote end, just use the ip address
108 // that we're currently communicating with as the hostname
110 // Spawn a debugserver and try to get the port it listens to.
111 ProcessLaunchInfo debugserver_launch_info;
112 if (hostname.empty())
113 hostname = "127.0.0.1";
115 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
117 log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
119 // Do not run in a new session so that it can not linger after the
121 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
122 debugserver_launch_info.SetMonitorProcessCallback(
123 std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
124 this, std::placeholders::_1),
127 llvm::StringRef platform_scheme;
128 llvm::StringRef platform_ip;
130 llvm::StringRef platform_path;
131 bool ok = UriParser::Parse(GetConnection()->GetURI(), platform_scheme,
132 platform_ip, platform_port, platform_path);
133 UNUSED_IF_ASSERT_DISABLED(ok);
136 std::ostringstream url;
137 // debugserver does not accept the URL scheme prefix.
138 #if !defined(__APPLE__)
139 url << m_socket_scheme << "://";
141 uint16_t *port_ptr = &port;
142 if (m_socket_protocol == Socket::ProtocolTcp)
143 url << platform_ip.str() << ":" << port;
145 socket_name = GetDomainSocketPath("gdbserver").GetPath();
150 Status error = StartDebugserverProcess(
151 url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
153 pid = debugserver_launch_info.GetProcessID();
154 if (pid != LLDB_INVALID_PROCESS_ID) {
155 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
156 m_spawned_pids.insert(pid);
158 AssociatePortWithProcess(port, pid);
166 GDBRemoteCommunication::PacketResult
167 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
168 StringExtractorGDBRemote &packet) {
170 return SendErrorResponse(9);
172 // Spawn a local debugserver as a platform so we can then attach or launch
175 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
177 log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
180 ConnectionFileDescriptor file_conn;
181 std::string hostname;
182 packet.SetFilePos(::strlen("qLaunchGDBServer;"));
183 llvm::StringRef name;
184 llvm::StringRef value;
185 uint16_t port = UINT16_MAX;
186 while (packet.GetNameColonValue(name, value)) {
187 if (name.equals("host"))
189 else if (name.equals("port"))
190 value.getAsInteger(0, port);
193 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
194 std::string socket_name;
196 LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
199 log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
201 __FUNCTION__, error.AsCString());
202 return SendErrorResponse(9);
206 log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
207 "launched successfully as pid %" PRIu64,
208 __FUNCTION__, debugserver_pid);
210 StreamGDBRemote response;
211 response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
212 port + m_port_offset);
213 if (!socket_name.empty()) {
214 response.PutCString("socket_name:");
215 response.PutCStringAsRawHex8(socket_name.c_str());
216 response.PutChar(';');
219 PacketResult packet_result = SendPacketNoLock(response.GetString());
220 if (packet_result != PacketResult::Success) {
221 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
222 ::kill(debugserver_pid, SIGINT);
224 return packet_result;
228 GDBRemoteCommunication::PacketResult
229 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
230 StringExtractorGDBRemote &packet) {
231 if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
232 return SendErrorResponse(4);
234 JSONObject::SP server_sp = std::make_shared<JSONObject>();
235 server_sp->SetObject("port",
236 std::make_shared<JSONNumber>(m_pending_gdb_server.port));
237 if (!m_pending_gdb_server.socket_name.empty())
238 server_sp->SetObject(
240 std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
242 JSONArray server_list;
243 server_list.AppendObject(server_sp);
245 StreamGDBRemote response;
246 server_list.Write(response);
248 StreamGDBRemote escaped_response;
249 escaped_response.PutEscapedBytes(response.GetString().data(),
251 return SendPacketNoLock(escaped_response.GetString());
254 GDBRemoteCommunication::PacketResult
255 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
256 StringExtractorGDBRemote &packet) {
257 packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
259 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
261 // verify that we know anything about this pid.
264 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
265 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
266 // not a pid we know about
267 return SendErrorResponse(10);
271 // go ahead and attempt to kill the spawned process
272 if (KillSpawnedProcess(pid))
273 return SendOKResponse();
275 return SendErrorResponse(11);
278 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
279 // make sure we know about this process
281 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
282 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
286 // first try a SIGTERM (standard kill)
287 Host::Kill(pid, SIGTERM);
289 // check if that worked
290 for (size_t i = 0; i < 10; ++i) {
292 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
293 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
301 // check one more time after the final usleep
303 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
304 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
308 // the launched process still lives. Now try killing it again,
309 // this time with an unblockable signal.
310 Host::Kill(pid, SIGKILL);
312 for (size_t i = 0; i < 10; ++i) {
314 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
315 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
323 // check one more time after the final usleep
326 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
327 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
331 // no luck - the process still lives
335 GDBRemoteCommunication::PacketResult
336 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
337 StringExtractorGDBRemote &packet) {
338 lldb::pid_t pid = m_process_launch_info.GetProcessID();
339 m_process_launch_info.Clear();
341 if (pid == LLDB_INVALID_PROCESS_ID)
342 return SendErrorResponse(1);
344 ProcessInstanceInfo proc_info;
345 if (!Host::GetProcessInfo(pid, proc_info))
346 return SendErrorResponse(1);
348 StreamString response;
349 CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
350 return SendPacketNoLock(response.GetString());
353 GDBRemoteCommunication::PacketResult
354 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
355 StringExtractorGDBRemote &packet) {
357 llvm::SmallString<64> cwd;
358 if (std::error_code ec = llvm::sys::fs::current_path(cwd))
359 return SendErrorResponse(ec.value());
361 StreamString response;
362 response.PutBytesAsRawHex8(cwd.data(), cwd.size());
363 return SendPacketNoLock(response.GetString());
366 GDBRemoteCommunication::PacketResult
367 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
368 StringExtractorGDBRemote &packet) {
369 packet.SetFilePos(::strlen("QSetWorkingDir:"));
371 packet.GetHexByteString(path);
373 if (std::error_code ec = llvm::sys::fs::set_current_path(path))
374 return SendErrorResponse(ec.value());
375 return SendOKResponse();
378 GDBRemoteCommunication::PacketResult
379 GDBRemoteCommunicationServerPlatform::Handle_qC(
380 StringExtractorGDBRemote &packet) {
381 // NOTE: lldb should now be using qProcessInfo for process IDs. This path
383 // should not be used. It is reporting process id instead of thread id. The
384 // correct answer doesn't seem to make much sense for lldb-platform.
385 // CONSIDER: flip to "unsupported".
386 lldb::pid_t pid = m_process_launch_info.GetProcessID();
388 StreamString response;
389 response.Printf("QC%" PRIx64, pid);
391 // If we launch a process and this GDB server is acting as a platform,
392 // then we need to clear the process launch state so we can start
393 // launching another process. In order to launch a process a bunch or
394 // packets need to be sent: environment packets, working directory,
395 // disable ASLR, and many more settings. When we launch a process we
396 // then need to know when to clear this information. Currently we are
397 // selecting the 'qC' packet as that packet which seems to make the most
399 if (pid != LLDB_INVALID_PROCESS_ID) {
400 m_process_launch_info.Clear();
403 return SendPacketNoLock(response.GetString());
406 GDBRemoteCommunication::PacketResult
407 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
408 StringExtractorGDBRemote &packet) {
409 StructuredData::Array signal_array;
411 const auto &signals = Host::GetUnixSignals();
412 for (auto signo = signals->GetFirstSignalNumber();
413 signo != LLDB_INVALID_SIGNAL_NUMBER;
414 signo = signals->GetNextSignalNumber(signo)) {
415 auto dictionary = std::make_shared<StructuredData::Dictionary>();
417 dictionary->AddIntegerItem("signo", signo);
418 dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
420 bool suppress, stop, notify;
421 signals->GetSignalInfo(signo, suppress, stop, notify);
422 dictionary->AddBooleanItem("suppress", suppress);
423 dictionary->AddBooleanItem("stop", stop);
424 dictionary->AddBooleanItem("notify", notify);
426 signal_array.Push(dictionary);
429 StreamString response;
430 signal_array.Dump(response);
431 return SendPacketNoLock(response.GetString());
434 bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
436 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
437 FreePortForProcess(pid);
438 m_spawned_pids.erase(pid);
442 Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
443 if (!m_process_launch_info.GetArguments().GetArgumentCount())
444 return Status("%s: no process command line specified to launch",
447 // specify the process monitor if not already set. This should
448 // generally be what happens since we need to reap started
450 if (!m_process_launch_info.GetMonitorProcessCallback())
451 m_process_launch_info.SetMonitorProcessCallback(
453 &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
454 this, std::placeholders::_1),
457 Status error = Host::LaunchProcess(m_process_launch_info);
458 if (!error.Success()) {
459 fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
460 m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
464 printf("Launched '%s' as process %" PRIu64 "...\n",
465 m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
466 m_process_launch_info.GetProcessID());
468 // add to list of spawned processes. On an lldb-gdbserver, we
469 // would expect there to be only one.
470 const auto pid = m_process_launch_info.GetProcessID();
471 if (pid != LLDB_INVALID_PROCESS_ID) {
472 // add to spawned pids
473 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
474 m_spawned_pids.insert(pid);
480 void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
481 m_port_map = port_map;
484 uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
485 if (m_port_map.empty())
486 return 0; // Bind to port zero and get a port, we didn't have any
489 for (auto &pair : m_port_map) {
490 if (pair.second == LLDB_INVALID_PROCESS_ID) {
491 pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
498 bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
499 uint16_t port, lldb::pid_t pid) {
500 PortMap::iterator pos = m_port_map.find(port);
501 if (pos != m_port_map.end()) {
508 bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
509 PortMap::iterator pos = m_port_map.find(port);
510 if (pos != m_port_map.end()) {
511 pos->second = LLDB_INVALID_PROCESS_ID;
517 bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
518 if (!m_port_map.empty()) {
519 for (auto &pair : m_port_map) {
520 if (pair.second == pid) {
521 pair.second = LLDB_INVALID_PROCESS_ID;
529 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
530 static FileSpec g_domainsocket_dir;
531 static llvm::once_flag g_once_flag;
533 llvm::call_once(g_once_flag, []() {
534 const char *domainsocket_dir_env =
535 ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
536 if (domainsocket_dir_env != nullptr)
537 g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
539 HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
542 return g_domainsocket_dir;
546 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
547 llvm::SmallString<PATH_MAX> socket_path;
548 llvm::SmallString<PATH_MAX> socket_name(
549 (llvm::StringRef(prefix) + ".%%%%%%").str());
551 FileSpec socket_path_spec(GetDomainSocketDir());
552 socket_path_spec.AppendPathComponent(socket_name.c_str());
554 llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
555 return FileSpec(socket_path.c_str(), false);
558 void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
559 m_port_offset = port_offset;
562 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
563 lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
564 m_pending_gdb_server.pid = pid;
565 m_pending_gdb_server.port = port;
566 m_pending_gdb_server.socket_name = socket_name;