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