1 //===-- source/Host/linux/Host.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 // C Includes
11 #include <stdio.h>
12 #include <sys/utsname.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <dirent.h>
16 #include <fcntl.h>
17 #ifndef __ANDROID__
18 #include <execinfo.h>
19 #endif
20 
21 // C++ Includes
22 // Other libraries and framework includes
23 // Project includes
24 #include "lldb/Core/Error.h"
25 #include "lldb/Core/Log.h"
26 #include "lldb/Target/Process.h"
27 
28 #include "lldb/Host/Host.h"
29 #include "lldb/Host/HostInfo.h"
30 #ifdef __ANDROID_NDK__
31 #include "lldb/Host/android/Android.h"
32 #endif
33 #include "lldb/Core/DataBufferHeap.h"
34 #include "lldb/Core/DataExtractor.h"
35 
36 #include "lldb/Core/ModuleSpec.h"
37 #include "lldb/Symbol/ObjectFile.h"
38 #include "Plugins/Process/Linux/ProcFileReader.h"
39 #include "Plugins/Process/Utility/LinuxSignals.h"
40 #include "Plugins/Process/Utility/MipsLinuxSignals.h"
41 using namespace lldb;
42 using namespace lldb_private;
43 
44 typedef enum ProcessStateFlags
45 {
46     eProcessStateRunning           = (1u << 0), // Running
47     eProcessStateSleeping          = (1u << 1), // Sleeping in an interruptible wait
48     eProcessStateWaiting           = (1u << 2), // Waiting in an uninterruptible disk sleep
49     eProcessStateZombie            = (1u << 3), // Zombie
50     eProcessStateTracedOrStopped   = (1u << 4), // Traced or stopped (on a signal)
51     eProcessStatePaging            = (1u << 5)  // Paging
52 } ProcessStateFlags;
53 
54 typedef struct ProcessStatInfo
55 {
56     lldb::pid_t ppid;           // Parent Process ID
57     uint32_t fProcessState;     // ProcessStateFlags
58 } ProcessStatInfo;
59 
60 // Get the process info with additional information from /proc/$PID/stat (like process state, and tracer pid).
61 static bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid);
62 
63 static bool
64 ReadProcPseudoFileStat (lldb::pid_t pid, ProcessStatInfo& stat_info)
65 {
66     // Read the /proc/$PID/stat file.
67     lldb::DataBufferSP buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer (pid, "stat");
68 
69     // The filename of the executable is stored in parenthesis right after the pid. We look for the closing
70     // parenthesis for the filename and work from there in case the name has something funky like ')' in it.
71     const char *filename_end = strrchr ((const char *)buf_sp->GetBytes(), ')');
72     if (filename_end)
73     {
74         char state = '\0';
75         int ppid = LLDB_INVALID_PROCESS_ID;
76 
77         // Read state and ppid.
78         sscanf (filename_end + 1, " %c %d", &state, &ppid);
79 
80         stat_info.ppid = ppid;
81 
82         switch (state)
83         {
84             case 'R':
85                 stat_info.fProcessState |= eProcessStateRunning;
86                 break;
87             case 'S':
88                 stat_info.fProcessState |= eProcessStateSleeping;
89                 break;
90             case 'D':
91                 stat_info.fProcessState |= eProcessStateWaiting;
92                 break;
93             case 'Z':
94                 stat_info.fProcessState |= eProcessStateZombie;
95                 break;
96             case 'T':
97                 stat_info.fProcessState |= eProcessStateTracedOrStopped;
98                 break;
99             case 'W':
100                 stat_info.fProcessState |= eProcessStatePaging;
101                 break;
102         }
103 
104         return true;
105     }
106 
107     return false;
108 }
109 
110 static void
111 GetLinuxProcessUserAndGroup (lldb::pid_t pid, ProcessInstanceInfo &process_info, lldb::pid_t &tracerpid)
112 {
113     tracerpid = 0;
114     uint32_t rUid = UINT32_MAX;     // Real User ID
115     uint32_t eUid = UINT32_MAX;     // Effective User ID
116     uint32_t rGid = UINT32_MAX;     // Real Group ID
117     uint32_t eGid = UINT32_MAX;     // Effective Group ID
118 
119     // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields.
120     lldb::DataBufferSP buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer (pid, "status");
121 
122     static const char uid_token[] = "Uid:";
123     char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token);
124     if (buf_uid)
125     {
126         // Real, effective, saved set, and file system UIDs. Read the first two.
127         buf_uid += sizeof(uid_token);
128         rUid = strtol (buf_uid, &buf_uid, 10);
129         eUid = strtol (buf_uid, &buf_uid, 10);
130     }
131 
132     static const char gid_token[] = "Gid:";
133     char *buf_gid = strstr ((char *)buf_sp->GetBytes(), gid_token);
134     if (buf_gid)
135     {
136         // Real, effective, saved set, and file system GIDs. Read the first two.
137         buf_gid += sizeof(gid_token);
138         rGid = strtol (buf_gid, &buf_gid, 10);
139         eGid = strtol (buf_gid, &buf_gid, 10);
140     }
141 
142     static const char tracerpid_token[] = "TracerPid:";
143     char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token);
144     if (buf_tracerpid)
145     {
146         // Tracer PID. 0 if we're not being debugged.
147         buf_tracerpid += sizeof(tracerpid_token);
148         tracerpid = strtol (buf_tracerpid, &buf_tracerpid, 10);
149     }
150 
151     process_info.SetUserID (rUid);
152     process_info.SetEffectiveUserID (eUid);
153     process_info.SetGroupID (rGid);
154     process_info.SetEffectiveGroupID (eGid);
155 }
156 
157 lldb::DataBufferSP
158 Host::GetAuxvData(lldb_private::Process *process)
159 {
160     return process_linux::ProcFileReader::ReadIntoDataBuffer (process->GetID(), "auxv");
161 }
162 
163 lldb::DataBufferSP
164 Host::GetAuxvData (lldb::pid_t pid)
165 {
166     return process_linux::ProcFileReader::ReadIntoDataBuffer (pid, "auxv");
167 }
168 
169 static bool
170 IsDirNumeric(const char *dname)
171 {
172     for (; *dname; dname++)
173     {
174         if (!isdigit (*dname))
175             return false;
176     }
177     return true;
178 }
179 
180 uint32_t
181 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
182 {
183     static const char procdir[] = "/proc/";
184 
185     DIR *dirproc = opendir (procdir);
186     if (dirproc)
187     {
188         struct dirent *direntry = NULL;
189         const uid_t our_uid = getuid();
190         const lldb::pid_t our_pid = getpid();
191         bool all_users = match_info.GetMatchAllUsers();
192 
193         while ((direntry = readdir (dirproc)) != NULL)
194         {
195             if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
196                 continue;
197 
198             lldb::pid_t pid = atoi (direntry->d_name);
199 
200             // Skip this process.
201             if (pid == our_pid)
202                 continue;
203 
204             lldb::pid_t tracerpid;
205             ProcessStatInfo stat_info;
206             ProcessInstanceInfo process_info;
207 
208             if (!GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid))
209                 continue;
210 
211             // Skip if process is being debugged.
212             if (tracerpid != 0)
213                 continue;
214 
215             // Skip zombies.
216             if (stat_info.fProcessState & eProcessStateZombie)
217                 continue;
218 
219             // Check for user match if we're not matching all users and not running as root.
220             if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
221                 continue;
222 
223             if (match_info.Matches (process_info))
224             {
225                 process_infos.Append (process_info);
226             }
227         }
228 
229         closedir (dirproc);
230     }
231 
232     return process_infos.GetSize();
233 }
234 
235 bool
236 Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
237 {
238     bool tids_changed = false;
239     static const char procdir[] = "/proc/";
240     static const char taskdir[] = "/task/";
241     std::string process_task_dir = procdir + std::to_string(pid) + taskdir;
242     DIR *dirproc = opendir (process_task_dir.c_str());
243 
244     if (dirproc)
245     {
246         struct dirent *direntry = NULL;
247         while ((direntry = readdir (dirproc)) != NULL)
248         {
249             if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
250                 continue;
251 
252             lldb::tid_t tid = atoi(direntry->d_name);
253             TidMap::iterator it = tids_to_attach.find(tid);
254             if (it == tids_to_attach.end())
255             {
256                 tids_to_attach.insert(TidPair(tid, false));
257                 tids_changed = true;
258             }
259         }
260         closedir (dirproc);
261     }
262 
263     return tids_changed;
264 }
265 
266 static bool
267 GetELFProcessCPUType (const char *exe_path, ProcessInstanceInfo &process_info)
268 {
269     // Clear the architecture.
270     process_info.GetArchitecture().Clear();
271 
272     ModuleSpecList specs;
273     FileSpec filespec (exe_path, false);
274     const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, 0, specs);
275     // GetModuleSpecifications() could fail if the executable has been deleted or is locked.
276     // But it shouldn't return more than 1 architecture.
277     assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
278     if (num_specs == 1)
279     {
280         ModuleSpec module_spec;
281         if (specs.GetModuleSpecAtIndex (0, module_spec) && module_spec.GetArchitecture().IsValid())
282         {
283             process_info.GetArchitecture () = module_spec.GetArchitecture();
284             return true;
285         }
286     }
287     return false;
288 }
289 
290 static bool
291 GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid)
292 {
293     tracerpid = 0;
294     process_info.Clear();
295     ::memset (&stat_info, 0, sizeof(stat_info));
296     stat_info.ppid = LLDB_INVALID_PROCESS_ID;
297 
298     // Use special code here because proc/[pid]/exe is a symbolic link.
299     char link_path[PATH_MAX];
300     char exe_path[PATH_MAX] = "";
301     if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
302         return false;
303 
304     ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
305     if (len <= 0)
306         return false;
307 
308     // readlink does not append a null byte.
309     exe_path[len] = 0;
310 
311     // If the binary has been deleted, the link name has " (deleted)" appended.
312     //  Remove if there.
313     static const ssize_t deleted_len = strlen(" (deleted)");
314     if (len > deleted_len &&
315         !strcmp(exe_path + len - deleted_len, " (deleted)"))
316     {
317         exe_path[len - deleted_len] = 0;
318     }
319     else
320     {
321         GetELFProcessCPUType (exe_path, process_info);
322     }
323 
324     process_info.SetProcessID(pid);
325     process_info.GetExecutableFile().SetFile(exe_path, false);
326     process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
327 
328     lldb::DataBufferSP buf_sp;
329 
330     // Get the process environment.
331     buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "environ");
332     Args &info_env = process_info.GetEnvironmentEntries();
333     char *next_var = (char *)buf_sp->GetBytes();
334     char *end_buf = next_var + buf_sp->GetByteSize();
335     while (next_var < end_buf && 0 != *next_var)
336     {
337         info_env.AppendArgument(next_var);
338         next_var += strlen(next_var) + 1;
339     }
340 
341     // Get the command line used to start the process.
342     buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "cmdline");
343 
344     // Grab Arg0 first, if there is one.
345     char *cmd = (char *)buf_sp->GetBytes();
346     if (cmd)
347     {
348         process_info.SetArg0(cmd);
349 
350         // Now process any remaining arguments.
351         Args &info_args = process_info.GetArguments();
352         char *next_arg = cmd + strlen(cmd) + 1;
353         end_buf = cmd + buf_sp->GetByteSize();
354         while (next_arg < end_buf && 0 != *next_arg)
355         {
356             info_args.AppendArgument(next_arg);
357             next_arg += strlen(next_arg) + 1;
358         }
359     }
360 
361     // Read /proc/$PID/stat to get our parent pid.
362     if (ReadProcPseudoFileStat (pid, stat_info))
363     {
364         process_info.SetParentProcessID (stat_info.ppid);
365     }
366 
367     // Get User and Group IDs and get tracer pid.
368     GetLinuxProcessUserAndGroup (pid, process_info, tracerpid);
369 
370     return true;
371 }
372 
373 bool
374 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
375 {
376     lldb::pid_t tracerpid;
377     ProcessStatInfo stat_info;
378 
379     return GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid);
380 }
381 
382 size_t
383 Host::GetEnvironment (StringList &env)
384 {
385     char **host_env = environ;
386     char *env_entry;
387     size_t i;
388     for (i=0; (env_entry = host_env[i]) != NULL; ++i)
389         env.AppendString(env_entry);
390     return i;
391 }
392 
393 // TODO: Generalize this with a function Host::GetSignals() as discussed at http://reviews.llvm.org/D10180
394 const lldb_private::UnixSignalsSP&
395 Host::GetUnixSignals ()
396 {
397     ArchSpec target_arch = HostInfoBase::GetArchitecture();
398     if(target_arch.GetTriple ().getArch () == llvm::Triple::mips64 ||
399        target_arch.GetTriple ().getArch () == llvm::Triple::mips64el ||
400        target_arch.GetTriple ().getArch () == llvm::Triple::mips ||
401        target_arch.GetTriple ().getArch () == llvm::Triple::mipsel) {
402         static const lldb_private::UnixSignalsSP s_unix_signals_sp (new process_linux::MipsLinuxSignals ());
403         return s_unix_signals_sp;
404     }
405     else
406     {
407         static const lldb_private::UnixSignalsSP s_unix_signals_sp (new process_linux::LinuxSignals ());
408         return s_unix_signals_sp;
409     }
410 
411 }
412 
413 Error
414 Host::ShellExpandArguments (ProcessLaunchInfo &launch_info)
415 {
416     return Error("unimplemented");
417 }
418