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