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