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