1 //===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "GDBRemoteCommunicationServerPlatform.h"
20 #include "llvm/Support/FileSystem.h"
21 #include "llvm/Support/JSON.h"
22 #include "llvm/Support/Threading.h"
24 #include "lldb/Host/Config.h"
25 #include "lldb/Host/ConnectionFileDescriptor.h"
26 #include "lldb/Host/FileAction.h"
27 #include "lldb/Host/Host.h"
28 #include "lldb/Host/HostInfo.h"
29 #include "lldb/Target/Platform.h"
30 #include "lldb/Target/UnixSignals.h"
31 #include "lldb/Utility/GDBRemote.h"
32 #include "lldb/Utility/Log.h"
33 #include "lldb/Utility/StreamString.h"
34 #include "lldb/Utility/StructuredData.h"
35 #include "lldb/Utility/UriParser.h"
37 #include "lldb/Utility/StringExtractorGDBRemote.h"
40 using namespace lldb_private::process_gdb_remote;
41 using namespace lldb_private;
43 // GDBRemoteCommunicationServerPlatform constructor
44 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
45 const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
46 : GDBRemoteCommunicationServerCommon("gdb-remote.server",
47 "gdb-remote.server.rx_packet"),
48 m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
49 m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
50 m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
51 m_pending_gdb_server.port = 0;
53 RegisterMemberFunctionHandler(
54 StringExtractorGDBRemote::eServerPacketType_qC,
55 &GDBRemoteCommunicationServerPlatform::Handle_qC);
56 RegisterMemberFunctionHandler(
57 StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
58 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
59 RegisterMemberFunctionHandler(
60 StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
61 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
62 RegisterMemberFunctionHandler(
63 StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
64 &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
65 RegisterMemberFunctionHandler(
66 StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
67 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
68 RegisterMemberFunctionHandler(
69 StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
70 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
71 RegisterMemberFunctionHandler(
72 StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
73 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
74 RegisterMemberFunctionHandler(
75 StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
76 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
78 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
79 [](StringExtractorGDBRemote packet, Status &error,
80 bool &interrupt, bool &quit) {
81 error.SetErrorString("interrupt received");
83 return PacketResult::Success;
88 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
90 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
91 const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
92 uint16_t &port, std::string &socket_name) {
93 if (port == UINT16_MAX)
94 port = GetNextAvailablePort();
96 // Spawn a new thread to accept the port that gets bound after binding to
99 // ignore the hostname send from the remote end, just use the ip address that
100 // we're currently communicating with as the hostname
102 // Spawn a debugserver and try to get the port it listens to.
103 ProcessLaunchInfo debugserver_launch_info;
104 if (hostname.empty())
105 hostname = "127.0.0.1";
107 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
108 LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
111 // Do not run in a new session so that it can not linger after the platform
113 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
114 debugserver_launch_info.SetMonitorProcessCallback(
115 std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
116 this, std::placeholders::_1),
119 std::ostringstream url;
120 // debugserver does not accept the URL scheme prefix.
121 #if !defined(__APPLE__)
122 url << m_socket_scheme << "://";
124 uint16_t *port_ptr = &port;
125 if (m_socket_protocol == Socket::ProtocolTcp) {
126 llvm::StringRef platform_scheme;
127 llvm::StringRef platform_ip;
129 llvm::StringRef platform_path;
130 std::string platform_uri = GetConnection()->GetURI();
131 bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
132 platform_port, platform_path);
133 UNUSED_IF_ASSERT_DISABLED(ok);
135 url << platform_ip.str() << ":" << port;
137 socket_name = GetDomainSocketPath("gdbserver").GetPath();
142 Status error = StartDebugserverProcess(
143 url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
145 pid = debugserver_launch_info.GetProcessID();
146 if (pid != LLDB_INVALID_PROCESS_ID) {
147 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
148 m_spawned_pids.insert(pid);
150 AssociatePortWithProcess(port, pid);
158 GDBRemoteCommunication::PacketResult
159 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
160 StringExtractorGDBRemote &packet) {
161 // Spawn a local debugserver as a platform so we can then attach or launch a
164 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
165 LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
168 ConnectionFileDescriptor file_conn;
169 std::string hostname;
170 packet.SetFilePos(::strlen("qLaunchGDBServer;"));
171 llvm::StringRef name;
172 llvm::StringRef value;
173 uint16_t port = UINT16_MAX;
174 while (packet.GetNameColonValue(name, value)) {
175 if (name.equals("host"))
177 else if (name.equals("port"))
178 value.getAsInteger(0, port);
181 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
182 std::string socket_name;
184 LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
187 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
189 __FUNCTION__, error.AsCString());
190 return SendErrorResponse(9);
194 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
195 "launched successfully as pid %" PRIu64,
196 __FUNCTION__, debugserver_pid);
198 StreamGDBRemote response;
199 response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
200 port + m_port_offset);
201 if (!socket_name.empty()) {
202 response.PutCString("socket_name:");
203 response.PutStringAsRawHex8(socket_name);
204 response.PutChar(';');
207 PacketResult packet_result = SendPacketNoLock(response.GetString());
208 if (packet_result != PacketResult::Success) {
209 if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
210 Host::Kill(debugserver_pid, SIGINT);
212 return packet_result;
215 GDBRemoteCommunication::PacketResult
216 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
217 StringExtractorGDBRemote &packet) {
218 namespace json = llvm::json;
220 if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
221 return SendErrorResponse(4);
223 json::Object server{{"port", m_pending_gdb_server.port}};
225 if (!m_pending_gdb_server.socket_name.empty())
226 server.try_emplace("socket_name", m_pending_gdb_server.socket_name);
228 json::Array server_list;
229 server_list.push_back(std::move(server));
231 StreamGDBRemote response;
232 response.AsRawOstream() << std::move(server_list);
234 StreamGDBRemote escaped_response;
235 escaped_response.PutEscapedBytes(response.GetString().data(),
237 return SendPacketNoLock(escaped_response.GetString());
240 GDBRemoteCommunication::PacketResult
241 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
242 StringExtractorGDBRemote &packet) {
243 packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
245 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
247 // verify that we know anything about this pid. Scope for locker
249 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
250 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
251 // not a pid we know about
252 return SendErrorResponse(10);
256 // go ahead and attempt to kill the spawned process
257 if (KillSpawnedProcess(pid))
258 return SendOKResponse();
260 return SendErrorResponse(11);
263 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
264 // make sure we know about this process
266 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
267 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
271 // first try a SIGTERM (standard kill)
272 Host::Kill(pid, SIGTERM);
274 // check if that worked
275 for (size_t i = 0; i < 10; ++i) {
277 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
278 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
283 std::this_thread::sleep_for(std::chrono::milliseconds(10));
287 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
288 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
292 // the launched process still lives. Now try killing it again, this time
293 // with an unblockable signal.
294 Host::Kill(pid, SIGKILL);
296 for (size_t i = 0; i < 10; ++i) {
298 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
299 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
304 std::this_thread::sleep_for(std::chrono::milliseconds(10));
307 // check one more time after the final sleep
309 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
310 if (m_spawned_pids.find(pid) == m_spawned_pids.end())
314 // no luck - the process still lives
318 GDBRemoteCommunication::PacketResult
319 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
320 StringExtractorGDBRemote &packet) {
321 lldb::pid_t pid = m_process_launch_info.GetProcessID();
322 m_process_launch_info.Clear();
324 if (pid == LLDB_INVALID_PROCESS_ID)
325 return SendErrorResponse(1);
327 ProcessInstanceInfo proc_info;
328 if (!Host::GetProcessInfo(pid, proc_info))
329 return SendErrorResponse(1);
331 StreamString response;
332 CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
333 return SendPacketNoLock(response.GetString());
336 GDBRemoteCommunication::PacketResult
337 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
338 StringExtractorGDBRemote &packet) {
340 llvm::SmallString<64> cwd;
341 if (std::error_code ec = llvm::sys::fs::current_path(cwd))
342 return SendErrorResponse(ec.value());
344 StreamString response;
345 response.PutBytesAsRawHex8(cwd.data(), cwd.size());
346 return SendPacketNoLock(response.GetString());
349 GDBRemoteCommunication::PacketResult
350 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
351 StringExtractorGDBRemote &packet) {
352 packet.SetFilePos(::strlen("QSetWorkingDir:"));
354 packet.GetHexByteString(path);
356 if (std::error_code ec = llvm::sys::fs::set_current_path(path))
357 return SendErrorResponse(ec.value());
358 return SendOKResponse();
361 GDBRemoteCommunication::PacketResult
362 GDBRemoteCommunicationServerPlatform::Handle_qC(
363 StringExtractorGDBRemote &packet) {
364 // NOTE: lldb should now be using qProcessInfo for process IDs. This path
366 // should not be used. It is reporting process id instead of thread id. The
367 // correct answer doesn't seem to make much sense for lldb-platform.
368 // CONSIDER: flip to "unsupported".
369 lldb::pid_t pid = m_process_launch_info.GetProcessID();
371 StreamString response;
372 response.Printf("QC%" PRIx64, pid);
374 // If we launch a process and this GDB server is acting as a platform, then
375 // we need to clear the process launch state so we can start launching
376 // another process. In order to launch a process a bunch or packets need to
377 // be sent: environment packets, working directory, disable ASLR, and many
378 // more settings. When we launch a process we then need to know when to clear
379 // this information. Currently we are selecting the 'qC' packet as that
380 // packet which seems to make the most sense.
381 if (pid != LLDB_INVALID_PROCESS_ID) {
382 m_process_launch_info.Clear();
385 return SendPacketNoLock(response.GetString());
388 GDBRemoteCommunication::PacketResult
389 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
390 StringExtractorGDBRemote &packet) {
391 StructuredData::Array signal_array;
393 lldb::UnixSignalsSP signals = UnixSignals::CreateForHost();
394 for (auto signo = signals->GetFirstSignalNumber();
395 signo != LLDB_INVALID_SIGNAL_NUMBER;
396 signo = signals->GetNextSignalNumber(signo)) {
397 auto dictionary = std::make_shared<StructuredData::Dictionary>();
399 dictionary->AddIntegerItem("signo", signo);
400 dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
402 bool suppress, stop, notify;
403 signals->GetSignalInfo(signo, suppress, stop, notify);
404 dictionary->AddBooleanItem("suppress", suppress);
405 dictionary->AddBooleanItem("stop", stop);
406 dictionary->AddBooleanItem("notify", notify);
408 signal_array.Push(dictionary);
411 StreamString response;
412 signal_array.Dump(response);
413 return SendPacketNoLock(response.GetString());
416 bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
418 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
419 FreePortForProcess(pid);
420 m_spawned_pids.erase(pid);
424 Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
425 if (!m_process_launch_info.GetArguments().GetArgumentCount())
426 return Status("%s: no process command line specified to launch",
429 // specify the process monitor if not already set. This should generally be
430 // what happens since we need to reap started processes.
431 if (!m_process_launch_info.GetMonitorProcessCallback())
432 m_process_launch_info.SetMonitorProcessCallback(
434 &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
435 this, std::placeholders::_1),
438 Status error = Host::LaunchProcess(m_process_launch_info);
439 if (!error.Success()) {
440 fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
441 m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
445 printf("Launched '%s' as process %" PRIu64 "...\n",
446 m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
447 m_process_launch_info.GetProcessID());
449 // add to list of spawned processes. On an lldb-gdbserver, we would expect
450 // there to be only one.
451 const auto pid = m_process_launch_info.GetProcessID();
452 if (pid != LLDB_INVALID_PROCESS_ID) {
453 // add to spawned pids
454 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
455 m_spawned_pids.insert(pid);
461 void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
462 m_port_map = port_map;
465 uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
466 if (m_port_map.empty())
467 return 0; // Bind to port zero and get a port, we didn't have any
470 for (auto &pair : m_port_map) {
471 if (pair.second == LLDB_INVALID_PROCESS_ID) {
472 pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
479 bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
480 uint16_t port, lldb::pid_t pid) {
481 PortMap::iterator pos = m_port_map.find(port);
482 if (pos != m_port_map.end()) {
489 bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
490 PortMap::iterator pos = m_port_map.find(port);
491 if (pos != m_port_map.end()) {
492 pos->second = LLDB_INVALID_PROCESS_ID;
498 bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
499 if (!m_port_map.empty()) {
500 for (auto &pair : m_port_map) {
501 if (pair.second == pid) {
502 pair.second = LLDB_INVALID_PROCESS_ID;
510 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
511 static FileSpec g_domainsocket_dir;
512 static llvm::once_flag g_once_flag;
514 llvm::call_once(g_once_flag, []() {
515 const char *domainsocket_dir_env =
516 ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
517 if (domainsocket_dir_env != nullptr)
518 g_domainsocket_dir = FileSpec(domainsocket_dir_env);
520 g_domainsocket_dir = HostInfo::GetProcessTempDir();
523 return g_domainsocket_dir;
527 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
528 llvm::SmallString<128> socket_path;
529 llvm::SmallString<128> socket_name(
530 (llvm::StringRef(prefix) + ".%%%%%%").str());
532 FileSpec socket_path_spec(GetDomainSocketDir());
533 socket_path_spec.AppendPathComponent(socket_name.c_str());
535 llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
536 return FileSpec(socket_path.c_str());
539 void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
540 m_port_offset = port_offset;
543 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
544 lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
545 m_pending_gdb_server.pid = pid;
546 m_pending_gdb_server.port = port;
547 m_pending_gdb_server.socket_name = socket_name;