1dda28197Spatrick //===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "GDBRemoteCommunicationServerPlatform.h"
10061da546Spatrick 
11*be691f3bSpatrick #include <cerrno>
12061da546Spatrick 
13061da546Spatrick #include <chrono>
14061da546Spatrick #include <csignal>
15061da546Spatrick #include <cstring>
16061da546Spatrick #include <mutex>
17061da546Spatrick #include <sstream>
18061da546Spatrick #include <thread>
19061da546Spatrick 
20061da546Spatrick #include "llvm/Support/FileSystem.h"
21061da546Spatrick #include "llvm/Support/JSON.h"
22061da546Spatrick #include "llvm/Support/Threading.h"
23061da546Spatrick 
24061da546Spatrick #include "lldb/Host/Config.h"
25061da546Spatrick #include "lldb/Host/ConnectionFileDescriptor.h"
26061da546Spatrick #include "lldb/Host/FileAction.h"
27061da546Spatrick #include "lldb/Host/Host.h"
28061da546Spatrick #include "lldb/Host/HostInfo.h"
29*be691f3bSpatrick #include "lldb/Interpreter/CommandCompletions.h"
30061da546Spatrick #include "lldb/Target/Platform.h"
31061da546Spatrick #include "lldb/Target/UnixSignals.h"
32061da546Spatrick #include "lldb/Utility/GDBRemote.h"
33061da546Spatrick #include "lldb/Utility/Log.h"
34061da546Spatrick #include "lldb/Utility/StreamString.h"
35061da546Spatrick #include "lldb/Utility/StructuredData.h"
36*be691f3bSpatrick #include "lldb/Utility/TildeExpressionResolver.h"
37061da546Spatrick #include "lldb/Utility/UriParser.h"
38061da546Spatrick 
39061da546Spatrick #include "lldb/Utility/StringExtractorGDBRemote.h"
40061da546Spatrick 
41061da546Spatrick using namespace lldb;
42061da546Spatrick using namespace lldb_private::process_gdb_remote;
43061da546Spatrick using namespace lldb_private;
44061da546Spatrick 
45*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::PortMap::PortMap(uint16_t min_port,
46*be691f3bSpatrick                                                        uint16_t max_port) {
47*be691f3bSpatrick   for (; min_port < max_port; ++min_port)
48*be691f3bSpatrick     m_port_map[min_port] = LLDB_INVALID_PROCESS_ID;
49*be691f3bSpatrick }
50*be691f3bSpatrick 
51*be691f3bSpatrick void GDBRemoteCommunicationServerPlatform::PortMap::AllowPort(uint16_t port) {
52*be691f3bSpatrick   // Do not modify existing mappings
53*be691f3bSpatrick   m_port_map.insert({port, LLDB_INVALID_PROCESS_ID});
54*be691f3bSpatrick }
55*be691f3bSpatrick 
56*be691f3bSpatrick llvm::Expected<uint16_t>
57*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::PortMap::GetNextAvailablePort() {
58*be691f3bSpatrick   if (m_port_map.empty())
59*be691f3bSpatrick     return 0; // Bind to port zero and get a port, we didn't have any
60*be691f3bSpatrick               // limitations
61*be691f3bSpatrick 
62*be691f3bSpatrick   for (auto &pair : m_port_map) {
63*be691f3bSpatrick     if (pair.second == LLDB_INVALID_PROCESS_ID) {
64*be691f3bSpatrick       pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
65*be691f3bSpatrick       return pair.first;
66*be691f3bSpatrick     }
67*be691f3bSpatrick   }
68*be691f3bSpatrick   return llvm::createStringError(llvm::inconvertibleErrorCode(),
69*be691f3bSpatrick                                  "No free port found in port map");
70*be691f3bSpatrick }
71*be691f3bSpatrick 
72*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::AssociatePortWithProcess(
73*be691f3bSpatrick     uint16_t port, lldb::pid_t pid) {
74*be691f3bSpatrick   auto pos = m_port_map.find(port);
75*be691f3bSpatrick   if (pos != m_port_map.end()) {
76*be691f3bSpatrick     pos->second = pid;
77*be691f3bSpatrick     return true;
78*be691f3bSpatrick   }
79*be691f3bSpatrick   return false;
80*be691f3bSpatrick }
81*be691f3bSpatrick 
82*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::FreePort(uint16_t port) {
83*be691f3bSpatrick   std::map<uint16_t, lldb::pid_t>::iterator pos = m_port_map.find(port);
84*be691f3bSpatrick   if (pos != m_port_map.end()) {
85*be691f3bSpatrick     pos->second = LLDB_INVALID_PROCESS_ID;
86*be691f3bSpatrick     return true;
87*be691f3bSpatrick   }
88*be691f3bSpatrick   return false;
89*be691f3bSpatrick }
90*be691f3bSpatrick 
91*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::FreePortForProcess(
92*be691f3bSpatrick     lldb::pid_t pid) {
93*be691f3bSpatrick   if (!m_port_map.empty()) {
94*be691f3bSpatrick     for (auto &pair : m_port_map) {
95*be691f3bSpatrick       if (pair.second == pid) {
96*be691f3bSpatrick         pair.second = LLDB_INVALID_PROCESS_ID;
97*be691f3bSpatrick         return true;
98*be691f3bSpatrick       }
99*be691f3bSpatrick     }
100*be691f3bSpatrick   }
101*be691f3bSpatrick   return false;
102*be691f3bSpatrick }
103*be691f3bSpatrick 
104*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::empty() const {
105*be691f3bSpatrick   return m_port_map.empty();
106*be691f3bSpatrick }
107*be691f3bSpatrick 
108061da546Spatrick // GDBRemoteCommunicationServerPlatform constructor
109061da546Spatrick GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
110061da546Spatrick     const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
111061da546Spatrick     : GDBRemoteCommunicationServerCommon("gdb-remote.server",
112061da546Spatrick                                          "gdb-remote.server.rx_packet"),
113061da546Spatrick       m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
114061da546Spatrick       m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
115061da546Spatrick   m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
116061da546Spatrick   m_pending_gdb_server.port = 0;
117061da546Spatrick 
118061da546Spatrick   RegisterMemberFunctionHandler(
119061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qC,
120061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qC);
121061da546Spatrick   RegisterMemberFunctionHandler(
122061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
123061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
124061da546Spatrick   RegisterMemberFunctionHandler(
125061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
126061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
127061da546Spatrick   RegisterMemberFunctionHandler(
128061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
129061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
130061da546Spatrick   RegisterMemberFunctionHandler(
131061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
132061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
133061da546Spatrick   RegisterMemberFunctionHandler(
134061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
135061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
136061da546Spatrick   RegisterMemberFunctionHandler(
137*be691f3bSpatrick       StringExtractorGDBRemote::eServerPacketType_qPathComplete,
138*be691f3bSpatrick       &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete);
139*be691f3bSpatrick   RegisterMemberFunctionHandler(
140061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
141061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
142061da546Spatrick   RegisterMemberFunctionHandler(
143061da546Spatrick       StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
144061da546Spatrick       &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
145061da546Spatrick 
146061da546Spatrick   RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
147061da546Spatrick                         [](StringExtractorGDBRemote packet, Status &error,
148061da546Spatrick                            bool &interrupt, bool &quit) {
149061da546Spatrick                           error.SetErrorString("interrupt received");
150061da546Spatrick                           interrupt = true;
151061da546Spatrick                           return PacketResult::Success;
152061da546Spatrick                         });
153061da546Spatrick }
154061da546Spatrick 
155061da546Spatrick // Destructor
156*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() =
157*be691f3bSpatrick     default;
158061da546Spatrick 
159061da546Spatrick Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
160061da546Spatrick     const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
161*be691f3bSpatrick     llvm::Optional<uint16_t> &port, std::string &socket_name) {
162*be691f3bSpatrick   if (!port) {
163*be691f3bSpatrick     llvm::Expected<uint16_t> available_port = m_port_map.GetNextAvailablePort();
164*be691f3bSpatrick     if (available_port)
165*be691f3bSpatrick       port = *available_port;
166*be691f3bSpatrick     else
167*be691f3bSpatrick       return Status(available_port.takeError());
168*be691f3bSpatrick   }
169061da546Spatrick 
170061da546Spatrick   // Spawn a new thread to accept the port that gets bound after binding to
171061da546Spatrick   // port 0 (zero).
172061da546Spatrick 
173061da546Spatrick   // ignore the hostname send from the remote end, just use the ip address that
174061da546Spatrick   // we're currently communicating with as the hostname
175061da546Spatrick 
176061da546Spatrick   // Spawn a debugserver and try to get the port it listens to.
177061da546Spatrick   ProcessLaunchInfo debugserver_launch_info;
178061da546Spatrick   if (hostname.empty())
179061da546Spatrick     hostname = "127.0.0.1";
180061da546Spatrick 
181061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
182061da546Spatrick   LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
183*be691f3bSpatrick             *port);
184061da546Spatrick 
185061da546Spatrick   // Do not run in a new session so that it can not linger after the platform
186061da546Spatrick   // closes.
187061da546Spatrick   debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
188061da546Spatrick   debugserver_launch_info.SetMonitorProcessCallback(
189061da546Spatrick       std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
190061da546Spatrick                 this, std::placeholders::_1),
191061da546Spatrick       false);
192061da546Spatrick 
193061da546Spatrick   std::ostringstream url;
194061da546Spatrick // debugserver does not accept the URL scheme prefix.
195061da546Spatrick #if !defined(__APPLE__)
196061da546Spatrick   url << m_socket_scheme << "://";
197061da546Spatrick #endif
198*be691f3bSpatrick   uint16_t *port_ptr = port.getPointer();
199061da546Spatrick   if (m_socket_protocol == Socket::ProtocolTcp) {
200061da546Spatrick     llvm::StringRef platform_scheme;
201061da546Spatrick     llvm::StringRef platform_ip;
202061da546Spatrick     int platform_port;
203061da546Spatrick     llvm::StringRef platform_path;
204061da546Spatrick     std::string platform_uri = GetConnection()->GetURI();
205061da546Spatrick     bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
206061da546Spatrick                                platform_port, platform_path);
207061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(ok);
208061da546Spatrick     assert(ok);
209*be691f3bSpatrick     url << '[' << platform_ip.str() << "]:" << *port;
210061da546Spatrick   } else {
211061da546Spatrick     socket_name = GetDomainSocketPath("gdbserver").GetPath();
212061da546Spatrick     url << socket_name;
213061da546Spatrick     port_ptr = nullptr;
214061da546Spatrick   }
215061da546Spatrick 
216061da546Spatrick   Status error = StartDebugserverProcess(
217061da546Spatrick       url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
218061da546Spatrick 
219061da546Spatrick   pid = debugserver_launch_info.GetProcessID();
220061da546Spatrick   if (pid != LLDB_INVALID_PROCESS_ID) {
221061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
222061da546Spatrick     m_spawned_pids.insert(pid);
223*be691f3bSpatrick     if (*port > 0)
224*be691f3bSpatrick       m_port_map.AssociatePortWithProcess(*port, pid);
225061da546Spatrick   } else {
226*be691f3bSpatrick     if (*port > 0)
227*be691f3bSpatrick       m_port_map.FreePort(*port);
228061da546Spatrick   }
229061da546Spatrick   return error;
230061da546Spatrick }
231061da546Spatrick 
232061da546Spatrick GDBRemoteCommunication::PacketResult
233061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
234061da546Spatrick     StringExtractorGDBRemote &packet) {
235061da546Spatrick   // Spawn a local debugserver as a platform so we can then attach or launch a
236061da546Spatrick   // process...
237061da546Spatrick 
238061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
239061da546Spatrick   LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
240061da546Spatrick             __FUNCTION__);
241061da546Spatrick 
242061da546Spatrick   ConnectionFileDescriptor file_conn;
243061da546Spatrick   std::string hostname;
244061da546Spatrick   packet.SetFilePos(::strlen("qLaunchGDBServer;"));
245061da546Spatrick   llvm::StringRef name;
246061da546Spatrick   llvm::StringRef value;
247*be691f3bSpatrick   llvm::Optional<uint16_t> port;
248061da546Spatrick   while (packet.GetNameColonValue(name, value)) {
249061da546Spatrick     if (name.equals("host"))
250dda28197Spatrick       hostname = std::string(value);
251*be691f3bSpatrick     else if (name.equals("port")) {
252*be691f3bSpatrick       // Make the Optional valid so we can use its value
253*be691f3bSpatrick       port = 0;
254*be691f3bSpatrick       value.getAsInteger(0, port.getValue());
255*be691f3bSpatrick     }
256061da546Spatrick   }
257061da546Spatrick 
258061da546Spatrick   lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
259061da546Spatrick   std::string socket_name;
260061da546Spatrick   Status error =
261061da546Spatrick       LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
262061da546Spatrick   if (error.Fail()) {
263061da546Spatrick     LLDB_LOGF(log,
264061da546Spatrick               "GDBRemoteCommunicationServerPlatform::%s() debugserver "
265061da546Spatrick               "launch failed: %s",
266061da546Spatrick               __FUNCTION__, error.AsCString());
267061da546Spatrick     return SendErrorResponse(9);
268061da546Spatrick   }
269061da546Spatrick 
270061da546Spatrick   LLDB_LOGF(log,
271061da546Spatrick             "GDBRemoteCommunicationServerPlatform::%s() debugserver "
272061da546Spatrick             "launched successfully as pid %" PRIu64,
273061da546Spatrick             __FUNCTION__, debugserver_pid);
274061da546Spatrick 
275061da546Spatrick   StreamGDBRemote response;
276*be691f3bSpatrick   assert(port);
277061da546Spatrick   response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
278*be691f3bSpatrick                   *port + m_port_offset);
279061da546Spatrick   if (!socket_name.empty()) {
280061da546Spatrick     response.PutCString("socket_name:");
281061da546Spatrick     response.PutStringAsRawHex8(socket_name);
282061da546Spatrick     response.PutChar(';');
283061da546Spatrick   }
284061da546Spatrick 
285061da546Spatrick   PacketResult packet_result = SendPacketNoLock(response.GetString());
286061da546Spatrick   if (packet_result != PacketResult::Success) {
287061da546Spatrick     if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
288061da546Spatrick       Host::Kill(debugserver_pid, SIGINT);
289061da546Spatrick   }
290061da546Spatrick   return packet_result;
291061da546Spatrick }
292061da546Spatrick 
293061da546Spatrick GDBRemoteCommunication::PacketResult
294061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
295061da546Spatrick     StringExtractorGDBRemote &packet) {
296061da546Spatrick   namespace json = llvm::json;
297061da546Spatrick 
298061da546Spatrick   if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
299061da546Spatrick     return SendErrorResponse(4);
300061da546Spatrick 
301061da546Spatrick   json::Object server{{"port", m_pending_gdb_server.port}};
302061da546Spatrick 
303061da546Spatrick   if (!m_pending_gdb_server.socket_name.empty())
304061da546Spatrick     server.try_emplace("socket_name", m_pending_gdb_server.socket_name);
305061da546Spatrick 
306061da546Spatrick   json::Array server_list;
307061da546Spatrick   server_list.push_back(std::move(server));
308061da546Spatrick 
309061da546Spatrick   StreamGDBRemote response;
310061da546Spatrick   response.AsRawOstream() << std::move(server_list);
311061da546Spatrick 
312061da546Spatrick   StreamGDBRemote escaped_response;
313061da546Spatrick   escaped_response.PutEscapedBytes(response.GetString().data(),
314061da546Spatrick                                    response.GetSize());
315061da546Spatrick   return SendPacketNoLock(escaped_response.GetString());
316061da546Spatrick }
317061da546Spatrick 
318061da546Spatrick GDBRemoteCommunication::PacketResult
319061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
320061da546Spatrick     StringExtractorGDBRemote &packet) {
321061da546Spatrick   packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
322061da546Spatrick 
323061da546Spatrick   lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
324061da546Spatrick 
325061da546Spatrick   // verify that we know anything about this pid. Scope for locker
326061da546Spatrick   {
327061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
328061da546Spatrick     if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
329061da546Spatrick       // not a pid we know about
330061da546Spatrick       return SendErrorResponse(10);
331061da546Spatrick     }
332061da546Spatrick   }
333061da546Spatrick 
334061da546Spatrick   // go ahead and attempt to kill the spawned process
335061da546Spatrick   if (KillSpawnedProcess(pid))
336061da546Spatrick     return SendOKResponse();
337061da546Spatrick   else
338061da546Spatrick     return SendErrorResponse(11);
339061da546Spatrick }
340061da546Spatrick 
341061da546Spatrick bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
342061da546Spatrick   // make sure we know about this process
343061da546Spatrick   {
344061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
345061da546Spatrick     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
346061da546Spatrick       return false;
347061da546Spatrick   }
348061da546Spatrick 
349061da546Spatrick   // first try a SIGTERM (standard kill)
350061da546Spatrick   Host::Kill(pid, SIGTERM);
351061da546Spatrick 
352061da546Spatrick   // check if that worked
353061da546Spatrick   for (size_t i = 0; i < 10; ++i) {
354061da546Spatrick     {
355061da546Spatrick       std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
356061da546Spatrick       if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
357061da546Spatrick         // it is now killed
358061da546Spatrick         return true;
359061da546Spatrick       }
360061da546Spatrick     }
361061da546Spatrick     std::this_thread::sleep_for(std::chrono::milliseconds(10));
362061da546Spatrick   }
363061da546Spatrick 
364061da546Spatrick   {
365061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
366061da546Spatrick     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
367061da546Spatrick       return true;
368061da546Spatrick   }
369061da546Spatrick 
370061da546Spatrick   // the launched process still lives.  Now try killing it again, this time
371061da546Spatrick   // with an unblockable signal.
372061da546Spatrick   Host::Kill(pid, SIGKILL);
373061da546Spatrick 
374061da546Spatrick   for (size_t i = 0; i < 10; ++i) {
375061da546Spatrick     {
376061da546Spatrick       std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
377061da546Spatrick       if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
378061da546Spatrick         // it is now killed
379061da546Spatrick         return true;
380061da546Spatrick       }
381061da546Spatrick     }
382061da546Spatrick     std::this_thread::sleep_for(std::chrono::milliseconds(10));
383061da546Spatrick   }
384061da546Spatrick 
385061da546Spatrick   // check one more time after the final sleep
386061da546Spatrick   {
387061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
388061da546Spatrick     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
389061da546Spatrick       return true;
390061da546Spatrick   }
391061da546Spatrick 
392061da546Spatrick   // no luck - the process still lives
393061da546Spatrick   return false;
394061da546Spatrick }
395061da546Spatrick 
396061da546Spatrick GDBRemoteCommunication::PacketResult
397061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
398061da546Spatrick     StringExtractorGDBRemote &packet) {
399061da546Spatrick   lldb::pid_t pid = m_process_launch_info.GetProcessID();
400061da546Spatrick   m_process_launch_info.Clear();
401061da546Spatrick 
402061da546Spatrick   if (pid == LLDB_INVALID_PROCESS_ID)
403061da546Spatrick     return SendErrorResponse(1);
404061da546Spatrick 
405061da546Spatrick   ProcessInstanceInfo proc_info;
406061da546Spatrick   if (!Host::GetProcessInfo(pid, proc_info))
407061da546Spatrick     return SendErrorResponse(1);
408061da546Spatrick 
409061da546Spatrick   StreamString response;
410061da546Spatrick   CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
411061da546Spatrick   return SendPacketNoLock(response.GetString());
412061da546Spatrick }
413061da546Spatrick 
414061da546Spatrick GDBRemoteCommunication::PacketResult
415*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::Handle_qPathComplete(
416*be691f3bSpatrick     StringExtractorGDBRemote &packet) {
417*be691f3bSpatrick   packet.SetFilePos(::strlen("qPathComplete:"));
418*be691f3bSpatrick   const bool only_dir = (packet.GetHexMaxU32(false, 0) == 1);
419*be691f3bSpatrick   if (packet.GetChar() != ',')
420*be691f3bSpatrick     return SendErrorResponse(85);
421*be691f3bSpatrick   std::string path;
422*be691f3bSpatrick   packet.GetHexByteString(path);
423*be691f3bSpatrick 
424*be691f3bSpatrick   StringList matches;
425*be691f3bSpatrick   StandardTildeExpressionResolver resolver;
426*be691f3bSpatrick   if (only_dir)
427*be691f3bSpatrick     CommandCompletions::DiskDirectories(path, matches, resolver);
428*be691f3bSpatrick   else
429*be691f3bSpatrick     CommandCompletions::DiskFiles(path, matches, resolver);
430*be691f3bSpatrick 
431*be691f3bSpatrick   StreamString response;
432*be691f3bSpatrick   response.PutChar('M');
433*be691f3bSpatrick   llvm::StringRef separator;
434*be691f3bSpatrick   std::sort(matches.begin(), matches.end());
435*be691f3bSpatrick   for (const auto &match : matches) {
436*be691f3bSpatrick     response << separator;
437*be691f3bSpatrick     separator = ",";
438*be691f3bSpatrick     // encode result strings into hex bytes to avoid unexpected error caused by
439*be691f3bSpatrick     // special characters like '$'.
440*be691f3bSpatrick     response.PutStringAsRawHex8(match.c_str());
441*be691f3bSpatrick   }
442*be691f3bSpatrick 
443*be691f3bSpatrick   return SendPacketNoLock(response.GetString());
444*be691f3bSpatrick }
445*be691f3bSpatrick 
446*be691f3bSpatrick GDBRemoteCommunication::PacketResult
447061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
448061da546Spatrick     StringExtractorGDBRemote &packet) {
449061da546Spatrick 
450061da546Spatrick   llvm::SmallString<64> cwd;
451061da546Spatrick   if (std::error_code ec = llvm::sys::fs::current_path(cwd))
452061da546Spatrick     return SendErrorResponse(ec.value());
453061da546Spatrick 
454061da546Spatrick   StreamString response;
455061da546Spatrick   response.PutBytesAsRawHex8(cwd.data(), cwd.size());
456061da546Spatrick   return SendPacketNoLock(response.GetString());
457061da546Spatrick }
458061da546Spatrick 
459061da546Spatrick GDBRemoteCommunication::PacketResult
460061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
461061da546Spatrick     StringExtractorGDBRemote &packet) {
462061da546Spatrick   packet.SetFilePos(::strlen("QSetWorkingDir:"));
463061da546Spatrick   std::string path;
464061da546Spatrick   packet.GetHexByteString(path);
465061da546Spatrick 
466061da546Spatrick   if (std::error_code ec = llvm::sys::fs::set_current_path(path))
467061da546Spatrick     return SendErrorResponse(ec.value());
468061da546Spatrick   return SendOKResponse();
469061da546Spatrick }
470061da546Spatrick 
471061da546Spatrick GDBRemoteCommunication::PacketResult
472061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qC(
473061da546Spatrick     StringExtractorGDBRemote &packet) {
474061da546Spatrick   // NOTE: lldb should now be using qProcessInfo for process IDs.  This path
475061da546Spatrick   // here
476061da546Spatrick   // should not be used.  It is reporting process id instead of thread id.  The
477061da546Spatrick   // correct answer doesn't seem to make much sense for lldb-platform.
478061da546Spatrick   // CONSIDER: flip to "unsupported".
479061da546Spatrick   lldb::pid_t pid = m_process_launch_info.GetProcessID();
480061da546Spatrick 
481061da546Spatrick   StreamString response;
482061da546Spatrick   response.Printf("QC%" PRIx64, pid);
483061da546Spatrick 
484061da546Spatrick   // If we launch a process and this GDB server is acting as a platform, then
485061da546Spatrick   // we need to clear the process launch state so we can start launching
486061da546Spatrick   // another process. In order to launch a process a bunch or packets need to
487061da546Spatrick   // be sent: environment packets, working directory, disable ASLR, and many
488061da546Spatrick   // more settings. When we launch a process we then need to know when to clear
489061da546Spatrick   // this information. Currently we are selecting the 'qC' packet as that
490061da546Spatrick   // packet which seems to make the most sense.
491061da546Spatrick   if (pid != LLDB_INVALID_PROCESS_ID) {
492061da546Spatrick     m_process_launch_info.Clear();
493061da546Spatrick   }
494061da546Spatrick 
495061da546Spatrick   return SendPacketNoLock(response.GetString());
496061da546Spatrick }
497061da546Spatrick 
498061da546Spatrick GDBRemoteCommunication::PacketResult
499061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
500061da546Spatrick     StringExtractorGDBRemote &packet) {
501061da546Spatrick   StructuredData::Array signal_array;
502061da546Spatrick 
503061da546Spatrick   lldb::UnixSignalsSP signals = UnixSignals::CreateForHost();
504061da546Spatrick   for (auto signo = signals->GetFirstSignalNumber();
505061da546Spatrick        signo != LLDB_INVALID_SIGNAL_NUMBER;
506061da546Spatrick        signo = signals->GetNextSignalNumber(signo)) {
507061da546Spatrick     auto dictionary = std::make_shared<StructuredData::Dictionary>();
508061da546Spatrick 
509061da546Spatrick     dictionary->AddIntegerItem("signo", signo);
510061da546Spatrick     dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
511061da546Spatrick 
512061da546Spatrick     bool suppress, stop, notify;
513061da546Spatrick     signals->GetSignalInfo(signo, suppress, stop, notify);
514061da546Spatrick     dictionary->AddBooleanItem("suppress", suppress);
515061da546Spatrick     dictionary->AddBooleanItem("stop", stop);
516061da546Spatrick     dictionary->AddBooleanItem("notify", notify);
517061da546Spatrick 
518061da546Spatrick     signal_array.Push(dictionary);
519061da546Spatrick   }
520061da546Spatrick 
521061da546Spatrick   StreamString response;
522061da546Spatrick   signal_array.Dump(response);
523061da546Spatrick   return SendPacketNoLock(response.GetString());
524061da546Spatrick }
525061da546Spatrick 
526061da546Spatrick bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
527061da546Spatrick     lldb::pid_t pid) {
528061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
529*be691f3bSpatrick   m_port_map.FreePortForProcess(pid);
530061da546Spatrick   m_spawned_pids.erase(pid);
531061da546Spatrick   return true;
532061da546Spatrick }
533061da546Spatrick 
534061da546Spatrick Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
535061da546Spatrick   if (!m_process_launch_info.GetArguments().GetArgumentCount())
536061da546Spatrick     return Status("%s: no process command line specified to launch",
537061da546Spatrick                   __FUNCTION__);
538061da546Spatrick 
539061da546Spatrick   // specify the process monitor if not already set.  This should generally be
540061da546Spatrick   // what happens since we need to reap started processes.
541061da546Spatrick   if (!m_process_launch_info.GetMonitorProcessCallback())
542061da546Spatrick     m_process_launch_info.SetMonitorProcessCallback(
543061da546Spatrick         std::bind(
544061da546Spatrick             &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
545061da546Spatrick             this, std::placeholders::_1),
546061da546Spatrick         false);
547061da546Spatrick 
548061da546Spatrick   Status error = Host::LaunchProcess(m_process_launch_info);
549061da546Spatrick   if (!error.Success()) {
550061da546Spatrick     fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
551061da546Spatrick             m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
552061da546Spatrick     return error;
553061da546Spatrick   }
554061da546Spatrick 
555061da546Spatrick   printf("Launched '%s' as process %" PRIu64 "...\n",
556061da546Spatrick          m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
557061da546Spatrick          m_process_launch_info.GetProcessID());
558061da546Spatrick 
559061da546Spatrick   // add to list of spawned processes.  On an lldb-gdbserver, we would expect
560061da546Spatrick   // there to be only one.
561061da546Spatrick   const auto pid = m_process_launch_info.GetProcessID();
562061da546Spatrick   if (pid != LLDB_INVALID_PROCESS_ID) {
563061da546Spatrick     // add to spawned pids
564061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
565061da546Spatrick     m_spawned_pids.insert(pid);
566061da546Spatrick   }
567061da546Spatrick 
568061da546Spatrick   return error;
569061da546Spatrick }
570061da546Spatrick 
571061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
572061da546Spatrick   m_port_map = port_map;
573061da546Spatrick }
574061da546Spatrick 
575061da546Spatrick const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
576061da546Spatrick   static FileSpec g_domainsocket_dir;
577061da546Spatrick   static llvm::once_flag g_once_flag;
578061da546Spatrick 
579061da546Spatrick   llvm::call_once(g_once_flag, []() {
580061da546Spatrick     const char *domainsocket_dir_env =
581061da546Spatrick         ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
582061da546Spatrick     if (domainsocket_dir_env != nullptr)
583061da546Spatrick       g_domainsocket_dir = FileSpec(domainsocket_dir_env);
584061da546Spatrick     else
585061da546Spatrick       g_domainsocket_dir = HostInfo::GetProcessTempDir();
586061da546Spatrick   });
587061da546Spatrick 
588061da546Spatrick   return g_domainsocket_dir;
589061da546Spatrick }
590061da546Spatrick 
591061da546Spatrick FileSpec
592061da546Spatrick GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
593061da546Spatrick   llvm::SmallString<128> socket_path;
594061da546Spatrick   llvm::SmallString<128> socket_name(
595061da546Spatrick       (llvm::StringRef(prefix) + ".%%%%%%").str());
596061da546Spatrick 
597061da546Spatrick   FileSpec socket_path_spec(GetDomainSocketDir());
598061da546Spatrick   socket_path_spec.AppendPathComponent(socket_name.c_str());
599061da546Spatrick 
600061da546Spatrick   llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
601061da546Spatrick   return FileSpec(socket_path.c_str());
602061da546Spatrick }
603061da546Spatrick 
604061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
605061da546Spatrick   m_port_offset = port_offset;
606061da546Spatrick }
607061da546Spatrick 
608061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
609061da546Spatrick     lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
610061da546Spatrick   m_pending_gdb_server.pid = pid;
611061da546Spatrick   m_pending_gdb_server.port = port;
612061da546Spatrick   m_pending_gdb_server.socket_name = socket_name;
613061da546Spatrick }
614