1 //===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "GDBRemoteCommunicationServerPlatform.h"
10 
11 #include <cerrno>
12 
13 #include <chrono>
14 #include <csignal>
15 #include <cstring>
16 #include <mutex>
17 #include <optional>
18 #include <sstream>
19 #include <thread>
20 
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/JSON.h"
23 #include "llvm/Support/Threading.h"
24 
25 #include "lldb/Host/Config.h"
26 #include "lldb/Host/ConnectionFileDescriptor.h"
27 #include "lldb/Host/FileAction.h"
28 #include "lldb/Host/Host.h"
29 #include "lldb/Host/HostInfo.h"
30 #include "lldb/Interpreter/CommandCompletions.h"
31 #include "lldb/Target/Platform.h"
32 #include "lldb/Target/UnixSignals.h"
33 #include "lldb/Utility/GDBRemote.h"
34 #include "lldb/Utility/LLDBLog.h"
35 #include "lldb/Utility/Log.h"
36 #include "lldb/Utility/StreamString.h"
37 #include "lldb/Utility/StructuredData.h"
38 #include "lldb/Utility/TildeExpressionResolver.h"
39 #include "lldb/Utility/UriParser.h"
40 
41 #include "lldb/Utility/StringExtractorGDBRemote.h"
42 
43 using namespace lldb;
44 using namespace lldb_private::process_gdb_remote;
45 using namespace lldb_private;
46 
PortMap(uint16_t min_port,uint16_t max_port)47 GDBRemoteCommunicationServerPlatform::PortMap::PortMap(uint16_t min_port,
48                                                        uint16_t max_port) {
49   assert(min_port);
50   for (; min_port < max_port; ++min_port)
51     m_port_map[min_port] = LLDB_INVALID_PROCESS_ID;
52 }
53 
AllowPort(uint16_t port)54 void GDBRemoteCommunicationServerPlatform::PortMap::AllowPort(uint16_t port) {
55   assert(port);
56   // Do not modify existing mappings
57   m_port_map.insert({port, LLDB_INVALID_PROCESS_ID});
58 }
59 
60 llvm::Expected<uint16_t>
GetNextAvailablePort()61 GDBRemoteCommunicationServerPlatform::PortMap::GetNextAvailablePort() {
62   if (m_port_map.empty())
63     return 0; // Bind to port zero and get a port, we didn't have any
64               // limitations
65 
66   for (auto &pair : m_port_map) {
67     if (pair.second == LLDB_INVALID_PROCESS_ID) {
68       pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
69       return pair.first;
70     }
71   }
72   return llvm::createStringError(llvm::inconvertibleErrorCode(),
73                                  "No free port found in port map");
74 }
75 
AssociatePortWithProcess(uint16_t port,lldb::pid_t pid)76 bool GDBRemoteCommunicationServerPlatform::PortMap::AssociatePortWithProcess(
77     uint16_t port, lldb::pid_t pid) {
78   auto pos = m_port_map.find(port);
79   if (pos != m_port_map.end()) {
80     pos->second = pid;
81     return true;
82   }
83   return false;
84 }
85 
FreePort(uint16_t port)86 bool GDBRemoteCommunicationServerPlatform::PortMap::FreePort(uint16_t port) {
87   std::map<uint16_t, lldb::pid_t>::iterator pos = m_port_map.find(port);
88   if (pos != m_port_map.end()) {
89     pos->second = LLDB_INVALID_PROCESS_ID;
90     return true;
91   }
92   return false;
93 }
94 
FreePortForProcess(lldb::pid_t pid)95 bool GDBRemoteCommunicationServerPlatform::PortMap::FreePortForProcess(
96     lldb::pid_t pid) {
97   if (!m_port_map.empty()) {
98     for (auto &pair : m_port_map) {
99       if (pair.second == pid) {
100         pair.second = LLDB_INVALID_PROCESS_ID;
101         return true;
102       }
103     }
104   }
105   return false;
106 }
107 
empty() const108 bool GDBRemoteCommunicationServerPlatform::PortMap::empty() const {
109   return m_port_map.empty();
110 }
111 
112 // GDBRemoteCommunicationServerPlatform constructor
GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,const char * socket_scheme)113 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
114     const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
115     : GDBRemoteCommunicationServerCommon(),
116       m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
117       m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
118   m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
119   m_pending_gdb_server.port = 0;
120 
121   RegisterMemberFunctionHandler(
122       StringExtractorGDBRemote::eServerPacketType_qC,
123       &GDBRemoteCommunicationServerPlatform::Handle_qC);
124   RegisterMemberFunctionHandler(
125       StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
126       &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
127   RegisterMemberFunctionHandler(
128       StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
129       &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
130   RegisterMemberFunctionHandler(
131       StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
132       &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
133   RegisterMemberFunctionHandler(
134       StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
135       &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
136   RegisterMemberFunctionHandler(
137       StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
138       &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
139   RegisterMemberFunctionHandler(
140       StringExtractorGDBRemote::eServerPacketType_qPathComplete,
141       &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete);
142   RegisterMemberFunctionHandler(
143       StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
144       &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
145   RegisterMemberFunctionHandler(
146       StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
147       &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
148 
149   RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
150                         [](StringExtractorGDBRemote packet, Status &error,
151                            bool &interrupt, bool &quit) {
152                           error.SetErrorString("interrupt received");
153                           interrupt = true;
154                           return PacketResult::Success;
155                         });
156 }
157 
158 // Destructor
159 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() =
160     default;
161 
LaunchGDBServer(const lldb_private::Args & args,std::string hostname,lldb::pid_t & pid,std::optional<uint16_t> & port,std::string & socket_name)162 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
163     const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
164     std::optional<uint16_t> &port, std::string &socket_name) {
165   if (!port) {
166     llvm::Expected<uint16_t> available_port = m_port_map.GetNextAvailablePort();
167     if (available_port)
168       port = *available_port;
169     else
170       return Status(available_port.takeError());
171   }
172 
173   // Spawn a new thread to accept the port that gets bound after binding to
174   // port 0 (zero).
175 
176   // ignore the hostname send from the remote end, just use the ip address that
177   // we're currently communicating with as the hostname
178 
179   // Spawn a debugserver and try to get the port it listens to.
180   ProcessLaunchInfo debugserver_launch_info;
181   if (hostname.empty())
182     hostname = "127.0.0.1";
183 
184   Log *log = GetLog(LLDBLog::Platform);
185   LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
186             *port);
187 
188   // Do not run in a new session so that it can not linger after the platform
189   // closes.
190   debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
191   debugserver_launch_info.SetMonitorProcessCallback(
192       std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
193                 this, std::placeholders::_1));
194 
195   std::ostringstream url;
196 // debugserver does not accept the URL scheme prefix.
197 #if !defined(__APPLE__)
198   url << m_socket_scheme << "://";
199 #endif
200   uint16_t *port_ptr = &*port;
201   if (m_socket_protocol == Socket::ProtocolTcp) {
202     std::string platform_uri = GetConnection()->GetURI();
203     std::optional<URI> parsed_uri = URI::Parse(platform_uri);
204     url << '[' << parsed_uri->hostname.str() << "]:" << *port;
205   } else {
206     socket_name = GetDomainSocketPath("gdbserver").GetPath();
207     url << socket_name;
208     port_ptr = nullptr;
209   }
210 
211   Status error = StartDebugserverProcess(
212       url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
213 
214   pid = debugserver_launch_info.GetProcessID();
215   if (pid != LLDB_INVALID_PROCESS_ID) {
216     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
217     m_spawned_pids.insert(pid);
218     if (*port > 0)
219       m_port_map.AssociatePortWithProcess(*port, pid);
220   } else {
221     if (*port > 0)
222       m_port_map.FreePort(*port);
223   }
224   return error;
225 }
226 
227 GDBRemoteCommunication::PacketResult
Handle_qLaunchGDBServer(StringExtractorGDBRemote & packet)228 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
229     StringExtractorGDBRemote &packet) {
230   // Spawn a local debugserver as a platform so we can then attach or launch a
231   // process...
232 
233   Log *log = GetLog(LLDBLog::Platform);
234   LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
235             __FUNCTION__);
236 
237   ConnectionFileDescriptor file_conn;
238   std::string hostname;
239   packet.SetFilePos(::strlen("qLaunchGDBServer;"));
240   llvm::StringRef name;
241   llvm::StringRef value;
242   std::optional<uint16_t> port;
243   while (packet.GetNameColonValue(name, value)) {
244     if (name == "host")
245       hostname = std::string(value);
246     else if (name == "port") {
247       // Make the Optional valid so we can use its value
248       port = 0;
249       value.getAsInteger(0, *port);
250     }
251   }
252 
253   lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
254   std::string socket_name;
255   Status error =
256       LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
257   if (error.Fail()) {
258     LLDB_LOGF(log,
259               "GDBRemoteCommunicationServerPlatform::%s() debugserver "
260               "launch failed: %s",
261               __FUNCTION__, error.AsCString());
262     return SendErrorResponse(9);
263   }
264 
265   LLDB_LOGF(log,
266             "GDBRemoteCommunicationServerPlatform::%s() debugserver "
267             "launched successfully as pid %" PRIu64,
268             __FUNCTION__, debugserver_pid);
269 
270   StreamGDBRemote response;
271   assert(port);
272   response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
273                   *port + m_port_offset);
274   if (!socket_name.empty()) {
275     response.PutCString("socket_name:");
276     response.PutStringAsRawHex8(socket_name);
277     response.PutChar(';');
278   }
279 
280   PacketResult packet_result = SendPacketNoLock(response.GetString());
281   if (packet_result != PacketResult::Success) {
282     if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
283       Host::Kill(debugserver_pid, SIGINT);
284   }
285   return packet_result;
286 }
287 
288 GDBRemoteCommunication::PacketResult
Handle_qQueryGDBServer(StringExtractorGDBRemote & packet)289 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
290     StringExtractorGDBRemote &packet) {
291   namespace json = llvm::json;
292 
293   if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
294     return SendErrorResponse(4);
295 
296   json::Object server{{"port", m_pending_gdb_server.port}};
297 
298   if (!m_pending_gdb_server.socket_name.empty())
299     server.try_emplace("socket_name", m_pending_gdb_server.socket_name);
300 
301   json::Array server_list;
302   server_list.push_back(std::move(server));
303 
304   StreamGDBRemote response;
305   response.AsRawOstream() << std::move(server_list);
306 
307   StreamGDBRemote escaped_response;
308   escaped_response.PutEscapedBytes(response.GetString().data(),
309                                    response.GetSize());
310   return SendPacketNoLock(escaped_response.GetString());
311 }
312 
313 GDBRemoteCommunication::PacketResult
Handle_qKillSpawnedProcess(StringExtractorGDBRemote & packet)314 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
315     StringExtractorGDBRemote &packet) {
316   packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
317 
318   lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
319 
320   // verify that we know anything about this pid. Scope for locker
321   {
322     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
323     if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
324       // not a pid we know about
325       return SendErrorResponse(10);
326     }
327   }
328 
329   // go ahead and attempt to kill the spawned process
330   if (KillSpawnedProcess(pid))
331     return SendOKResponse();
332   else
333     return SendErrorResponse(11);
334 }
335 
KillSpawnedProcess(lldb::pid_t pid)336 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
337   // make sure we know about this process
338   {
339     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
340     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
341       return false;
342   }
343 
344   // first try a SIGTERM (standard kill)
345   Host::Kill(pid, SIGTERM);
346 
347   // check if that worked
348   for (size_t i = 0; i < 10; ++i) {
349     {
350       std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
351       if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
352         // it is now killed
353         return true;
354       }
355     }
356     std::this_thread::sleep_for(std::chrono::milliseconds(10));
357   }
358 
359   {
360     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
361     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
362       return true;
363   }
364 
365   // the launched process still lives.  Now try killing it again, this time
366   // with an unblockable signal.
367   Host::Kill(pid, SIGKILL);
368 
369   for (size_t i = 0; i < 10; ++i) {
370     {
371       std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
372       if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
373         // it is now killed
374         return true;
375       }
376     }
377     std::this_thread::sleep_for(std::chrono::milliseconds(10));
378   }
379 
380   // check one more time after the final sleep
381   {
382     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
383     if (m_spawned_pids.find(pid) == m_spawned_pids.end())
384       return true;
385   }
386 
387   // no luck - the process still lives
388   return false;
389 }
390 
391 GDBRemoteCommunication::PacketResult
Handle_qProcessInfo(StringExtractorGDBRemote & packet)392 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
393     StringExtractorGDBRemote &packet) {
394   lldb::pid_t pid = m_process_launch_info.GetProcessID();
395   m_process_launch_info.Clear();
396 
397   if (pid == LLDB_INVALID_PROCESS_ID)
398     return SendErrorResponse(1);
399 
400   ProcessInstanceInfo proc_info;
401   if (!Host::GetProcessInfo(pid, proc_info))
402     return SendErrorResponse(1);
403 
404   StreamString response;
405   CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
406   return SendPacketNoLock(response.GetString());
407 }
408 
409 GDBRemoteCommunication::PacketResult
Handle_qPathComplete(StringExtractorGDBRemote & packet)410 GDBRemoteCommunicationServerPlatform::Handle_qPathComplete(
411     StringExtractorGDBRemote &packet) {
412   packet.SetFilePos(::strlen("qPathComplete:"));
413   const bool only_dir = (packet.GetHexMaxU32(false, 0) == 1);
414   if (packet.GetChar() != ',')
415     return SendErrorResponse(85);
416   std::string path;
417   packet.GetHexByteString(path);
418 
419   StringList matches;
420   StandardTildeExpressionResolver resolver;
421   if (only_dir)
422     CommandCompletions::DiskDirectories(path, matches, resolver);
423   else
424     CommandCompletions::DiskFiles(path, matches, resolver);
425 
426   StreamString response;
427   response.PutChar('M');
428   llvm::StringRef separator;
429   std::sort(matches.begin(), matches.end());
430   for (const auto &match : matches) {
431     response << separator;
432     separator = ",";
433     // encode result strings into hex bytes to avoid unexpected error caused by
434     // special characters like '$'.
435     response.PutStringAsRawHex8(match.c_str());
436   }
437 
438   return SendPacketNoLock(response.GetString());
439 }
440 
441 GDBRemoteCommunication::PacketResult
Handle_qGetWorkingDir(StringExtractorGDBRemote & packet)442 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
443     StringExtractorGDBRemote &packet) {
444 
445   llvm::SmallString<64> cwd;
446   if (std::error_code ec = llvm::sys::fs::current_path(cwd))
447     return SendErrorResponse(ec.value());
448 
449   StreamString response;
450   response.PutBytesAsRawHex8(cwd.data(), cwd.size());
451   return SendPacketNoLock(response.GetString());
452 }
453 
454 GDBRemoteCommunication::PacketResult
Handle_QSetWorkingDir(StringExtractorGDBRemote & packet)455 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
456     StringExtractorGDBRemote &packet) {
457   packet.SetFilePos(::strlen("QSetWorkingDir:"));
458   std::string path;
459   packet.GetHexByteString(path);
460 
461   if (std::error_code ec = llvm::sys::fs::set_current_path(path))
462     return SendErrorResponse(ec.value());
463   return SendOKResponse();
464 }
465 
466 GDBRemoteCommunication::PacketResult
Handle_qC(StringExtractorGDBRemote & packet)467 GDBRemoteCommunicationServerPlatform::Handle_qC(
468     StringExtractorGDBRemote &packet) {
469   // NOTE: lldb should now be using qProcessInfo for process IDs.  This path
470   // here
471   // should not be used.  It is reporting process id instead of thread id.  The
472   // correct answer doesn't seem to make much sense for lldb-platform.
473   // CONSIDER: flip to "unsupported".
474   lldb::pid_t pid = m_process_launch_info.GetProcessID();
475 
476   StreamString response;
477   response.Printf("QC%" PRIx64, pid);
478 
479   // If we launch a process and this GDB server is acting as a platform, then
480   // we need to clear the process launch state so we can start launching
481   // another process. In order to launch a process a bunch or packets need to
482   // be sent: environment packets, working directory, disable ASLR, and many
483   // more settings. When we launch a process we then need to know when to clear
484   // this information. Currently we are selecting the 'qC' packet as that
485   // packet which seems to make the most sense.
486   if (pid != LLDB_INVALID_PROCESS_ID) {
487     m_process_launch_info.Clear();
488   }
489 
490   return SendPacketNoLock(response.GetString());
491 }
492 
493 GDBRemoteCommunication::PacketResult
Handle_jSignalsInfo(StringExtractorGDBRemote & packet)494 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
495     StringExtractorGDBRemote &packet) {
496   StructuredData::Array signal_array;
497 
498   lldb::UnixSignalsSP signals = UnixSignals::CreateForHost();
499   for (auto signo = signals->GetFirstSignalNumber();
500        signo != LLDB_INVALID_SIGNAL_NUMBER;
501        signo = signals->GetNextSignalNumber(signo)) {
502     auto dictionary = std::make_shared<StructuredData::Dictionary>();
503 
504     dictionary->AddIntegerItem("signo", signo);
505     dictionary->AddStringItem("name", signals->GetSignalAsStringRef(signo));
506 
507     bool suppress, stop, notify;
508     signals->GetSignalInfo(signo, suppress, stop, notify);
509     dictionary->AddBooleanItem("suppress", suppress);
510     dictionary->AddBooleanItem("stop", stop);
511     dictionary->AddBooleanItem("notify", notify);
512 
513     signal_array.Push(dictionary);
514   }
515 
516   StreamString response;
517   signal_array.Dump(response);
518   return SendPacketNoLock(response.GetString());
519 }
520 
DebugserverProcessReaped(lldb::pid_t pid)521 void GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
522     lldb::pid_t pid) {
523   std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
524   m_port_map.FreePortForProcess(pid);
525   m_spawned_pids.erase(pid);
526 }
527 
LaunchProcess()528 Status GDBRemoteCommunicationServerPlatform::LaunchProcess() {
529   if (!m_process_launch_info.GetArguments().GetArgumentCount())
530     return Status("%s: no process command line specified to launch",
531                   __FUNCTION__);
532 
533   // specify the process monitor if not already set.  This should generally be
534   // what happens since we need to reap started processes.
535   if (!m_process_launch_info.GetMonitorProcessCallback())
536     m_process_launch_info.SetMonitorProcessCallback(std::bind(
537         &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this,
538         std::placeholders::_1));
539 
540   Status error = Host::LaunchProcess(m_process_launch_info);
541   if (!error.Success()) {
542     fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
543             m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
544     return error;
545   }
546 
547   printf("Launched '%s' as process %" PRIu64 "...\n",
548          m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
549          m_process_launch_info.GetProcessID());
550 
551   // add to list of spawned processes.  On an lldb-gdbserver, we would expect
552   // there to be only one.
553   const auto pid = m_process_launch_info.GetProcessID();
554   if (pid != LLDB_INVALID_PROCESS_ID) {
555     // add to spawned pids
556     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
557     m_spawned_pids.insert(pid);
558   }
559 
560   return error;
561 }
562 
SetPortMap(PortMap && port_map)563 void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
564   m_port_map = std::move(port_map);
565 }
566 
GetDomainSocketDir()567 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
568   static FileSpec g_domainsocket_dir;
569   static llvm::once_flag g_once_flag;
570 
571   llvm::call_once(g_once_flag, []() {
572     const char *domainsocket_dir_env =
573         ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
574     if (domainsocket_dir_env != nullptr)
575       g_domainsocket_dir = FileSpec(domainsocket_dir_env);
576     else
577       g_domainsocket_dir = HostInfo::GetProcessTempDir();
578   });
579 
580   return g_domainsocket_dir;
581 }
582 
583 FileSpec
GetDomainSocketPath(const char * prefix)584 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
585   llvm::SmallString<128> socket_path;
586   llvm::SmallString<128> socket_name(
587       (llvm::StringRef(prefix) + ".%%%%%%").str());
588 
589   FileSpec socket_path_spec(GetDomainSocketDir());
590   socket_path_spec.AppendPathComponent(socket_name.c_str());
591 
592   llvm::sys::fs::createUniqueFile(socket_path_spec.GetPath().c_str(),
593                                   socket_path);
594   return FileSpec(socket_path.c_str());
595 }
596 
SetPortOffset(uint16_t port_offset)597 void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
598   m_port_offset = port_offset;
599 }
600 
SetPendingGdbServer(lldb::pid_t pid,uint16_t port,const std::string & socket_name)601 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
602     lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
603   m_pending_gdb_server.pid = pid;
604   m_pending_gdb_server.port = port;
605   m_pending_gdb_server.socket_name = socket_name;
606 }
607