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