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