xref: /openbsd-src/gnu/llvm/lldb/source/Host/linux/Host.cpp (revision fcde59b201a29a2b4570b00b71e7aa25d61cb5c1)
1 //===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
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 <dirent.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <sys/utsname.h>
17 #include <unistd.h>
18 
19 #include "llvm/Object/ELF.h"
20 #include "llvm/Support/ScopedPrinter.h"
21 
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/ProcessInfo.h"
24 #include "lldb/Utility/Status.h"
25 
26 #include "lldb/Host/FileSystem.h"
27 #include "lldb/Host/Host.h"
28 #include "lldb/Host/HostInfo.h"
29 #include "lldb/Host/linux/Support.h"
30 #include "lldb/Utility/DataExtractor.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 namespace {
36 enum class ProcessState {
37   Unknown,
38   DiskSleep,
39   Paging,
40   Running,
41   Sleeping,
42   TracedOrStopped,
43   Zombie,
44 };
45 }
46 
47 namespace lldb_private {
48 class ProcessLaunchInfo;
49 }
50 
51 static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
52                           ProcessState &State, ::pid_t &TracerPid) {
53   auto BufferOrError = getProcFile(Pid, "status");
54   if (!BufferOrError)
55     return false;
56 
57   llvm::StringRef Rest = BufferOrError.get()->getBuffer();
58   while(!Rest.empty()) {
59     llvm::StringRef Line;
60     std::tie(Line, Rest) = Rest.split('\n');
61 
62     if (Line.consume_front("Gid:")) {
63       // Real, effective, saved set, and file system GIDs. Read the first two.
64       Line = Line.ltrim();
65       uint32_t RGid, EGid;
66       Line.consumeInteger(10, RGid);
67       Line = Line.ltrim();
68       Line.consumeInteger(10, EGid);
69 
70       ProcessInfo.SetGroupID(RGid);
71       ProcessInfo.SetEffectiveGroupID(EGid);
72     } else if (Line.consume_front("Uid:")) {
73       // Real, effective, saved set, and file system UIDs. Read the first two.
74       Line = Line.ltrim();
75       uint32_t RUid, EUid;
76       Line.consumeInteger(10, RUid);
77       Line = Line.ltrim();
78       Line.consumeInteger(10, EUid);
79 
80       ProcessInfo.SetUserID(RUid);
81       ProcessInfo.SetEffectiveUserID(EUid);
82     } else if (Line.consume_front("PPid:")) {
83       ::pid_t PPid;
84       Line.ltrim().consumeInteger(10, PPid);
85       ProcessInfo.SetParentProcessID(PPid);
86     } else if (Line.consume_front("State:")) {
87       char S = Line.ltrim().front();
88       switch (S) {
89       case 'R':
90         State = ProcessState::Running;
91         break;
92       case 'S':
93         State = ProcessState::Sleeping;
94         break;
95       case 'D':
96         State = ProcessState::DiskSleep;
97         break;
98       case 'Z':
99         State = ProcessState::Zombie;
100         break;
101       case 'T':
102         State = ProcessState::TracedOrStopped;
103         break;
104       case 'W':
105         State = ProcessState::Paging;
106         break;
107       }
108     } else if (Line.consume_front("TracerPid:")) {
109       Line = Line.ltrim();
110       Line.consumeInteger(10, TracerPid);
111     }
112   }
113   return true;
114 }
115 
116 static bool IsDirNumeric(const char *dname) {
117   for (; *dname; dname++) {
118     if (!isdigit(*dname))
119       return false;
120   }
121   return true;
122 }
123 
124 static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
125   Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
126 
127   auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
128   if (!buffer_sp)
129     return ArchSpec();
130 
131   uint8_t exe_class =
132       llvm::object::getElfArchType(
133           {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
134           .first;
135 
136   switch (exe_class) {
137   case llvm::ELF::ELFCLASS32:
138     return HostInfo::GetArchitecture(HostInfo::eArchKind32);
139   case llvm::ELF::ELFCLASS64:
140     return HostInfo::GetArchitecture(HostInfo::eArchKind64);
141   default:
142     LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
143     return ArchSpec();
144   }
145 }
146 
147 static void GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) {
148   auto BufferOrError = getProcFile(pid, "cmdline");
149   if (!BufferOrError)
150     return;
151   std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);
152 
153   llvm::StringRef Arg0, Rest;
154   std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
155   process_info.SetArg0(Arg0);
156   while (!Rest.empty()) {
157     llvm::StringRef Arg;
158     std::tie(Arg, Rest) = Rest.split('\0');
159     process_info.GetArguments().AppendArgument(Arg);
160   }
161 }
162 
163 static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
164   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
165   std::string ExePath(PATH_MAX, '\0');
166 
167   // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
168   llvm::SmallString<64> ProcExe;
169   (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
170 
171   ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
172   if (len > 0) {
173     ExePath.resize(len);
174   } else {
175     LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
176              Status(errno, eErrorTypePOSIX));
177     ExePath.resize(0);
178   }
179   // If the binary has been deleted, the link name has " (deleted)" appended.
180   // Remove if there.
181   llvm::StringRef PathRef = ExePath;
182   PathRef.consume_back(" (deleted)");
183 
184   if (!PathRef.empty()) {
185     process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
186     process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
187   }
188 }
189 
190 static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) {
191   // Get the process environment.
192   auto BufferOrError = getProcFile(pid, "environ");
193   if (!BufferOrError)
194     return;
195 
196   std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
197   llvm::StringRef Rest = Environ->getBuffer();
198   while (!Rest.empty()) {
199     llvm::StringRef Var;
200     std::tie(Var, Rest) = Rest.split('\0');
201     process_info.GetEnvironment().insert(Var);
202   }
203 }
204 
205 static bool GetProcessAndStatInfo(::pid_t pid,
206                                   ProcessInstanceInfo &process_info,
207                                   ProcessState &State, ::pid_t &tracerpid) {
208   tracerpid = 0;
209   process_info.Clear();
210 
211   process_info.SetProcessID(pid);
212 
213   GetExePathAndArch(pid, process_info);
214   GetProcessArgs(pid, process_info);
215   GetProcessEnviron(pid, process_info);
216 
217   // Get User and Group IDs and get tracer pid.
218   if (!GetStatusInfo(pid, process_info, State, tracerpid))
219     return false;
220 
221   return true;
222 }
223 
224 uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
225                              ProcessInstanceInfoList &process_infos) {
226   static const char procdir[] = "/proc/";
227 
228   DIR *dirproc = opendir(procdir);
229   if (dirproc) {
230     struct dirent *direntry = nullptr;
231     const uid_t our_uid = getuid();
232     const lldb::pid_t our_pid = getpid();
233     bool all_users = match_info.GetMatchAllUsers();
234 
235     while ((direntry = readdir(dirproc)) != nullptr) {
236       if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
237         continue;
238 
239       lldb::pid_t pid = atoi(direntry->d_name);
240 
241       // Skip this process.
242       if (pid == our_pid)
243         continue;
244 
245       ::pid_t tracerpid;
246       ProcessState State;
247       ProcessInstanceInfo process_info;
248 
249       if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
250         continue;
251 
252       // Skip if process is being debugged.
253       if (tracerpid != 0)
254         continue;
255 
256       if (State == ProcessState::Zombie)
257         continue;
258 
259       // Check for user match if we're not matching all users and not running
260       // as root.
261       if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
262         continue;
263 
264       if (match_info.Matches(process_info)) {
265         process_infos.Append(process_info);
266       }
267     }
268 
269     closedir(dirproc);
270   }
271 
272   return process_infos.GetSize();
273 }
274 
275 bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
276   bool tids_changed = false;
277   static const char procdir[] = "/proc/";
278   static const char taskdir[] = "/task/";
279   std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
280   DIR *dirproc = opendir(process_task_dir.c_str());
281 
282   if (dirproc) {
283     struct dirent *direntry = nullptr;
284     while ((direntry = readdir(dirproc)) != nullptr) {
285       if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
286         continue;
287 
288       lldb::tid_t tid = atoi(direntry->d_name);
289       TidMap::iterator it = tids_to_attach.find(tid);
290       if (it == tids_to_attach.end()) {
291         tids_to_attach.insert(TidPair(tid, false));
292         tids_changed = true;
293       }
294     }
295     closedir(dirproc);
296   }
297 
298   return tids_changed;
299 }
300 
301 bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
302   ::pid_t tracerpid;
303   ProcessState State;
304   return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
305 }
306 
307 Environment Host::GetEnvironment() { return Environment(environ); }
308 
309 Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
310   return Status("unimplemented");
311 }
312