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