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