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