LLDB mainline
aix/Host.cpp
Go to the documentation of this file.
1//===-- source/Host/aix/Host.cpp ----------------------------------------===//
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 "lldb/Host/Host.h"
12#include "lldb/Utility/Log.h"
14#include "lldb/Utility/Status.h"
15#include "llvm/BinaryFormat/XCOFF.h"
16#include <dirent.h>
17#include <sys/proc.h>
18#include <sys/procfs.h>
19
20using namespace lldb;
21using namespace lldb_private;
22
23namespace {
24enum class ProcessState {
25 Unknown,
26 Dead,
27 DiskSleep,
28 Idle,
29 Paging,
30 Parked,
31 Running,
32 Sleeping,
33 TracedOrStopped,
34 Zombie,
35};
36}
37
38static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) {
40 ts.tv_sec = t.tv_sec;
41 ts.tv_usec = t.tv_nsec / 1000; // nanos to micros
42 return ts;
43}
44
45static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo,
46 ProcessState &State) {
47 struct pstatus pstatusData;
48 auto BufferOrError = getProcFile(pid, "status");
49 if (!BufferOrError)
50 return false;
51
52 std::unique_ptr<llvm::MemoryBuffer> StatusBuffer = std::move(*BufferOrError);
53 // Ensure there's enough data for psinfoData
54 if (StatusBuffer->getBufferSize() < sizeof(pstatusData))
55 return false;
56
57 std::memcpy(&pstatusData, StatusBuffer->getBufferStart(),
58 sizeof(pstatusData));
59 switch (pstatusData.pr_stat) {
60 case SIDL:
61 State = ProcessState::Idle;
62 break;
63 case SACTIVE:
64 State = ProcessState::Running;
65 break;
66 case SSTOP:
67 State = ProcessState::TracedOrStopped;
68 break;
69 case SZOMB:
70 State = ProcessState::Zombie;
71 break;
72 default:
73 State = ProcessState::Unknown;
74 break;
75 }
76 processInfo.SetIsZombie(State == ProcessState::Zombie);
77 processInfo.SetUserTime(convert(pstatusData.pr_utime));
78 processInfo.SetSystemTime(convert(pstatusData.pr_stime));
79 processInfo.SetCumulativeUserTime(convert(pstatusData.pr_cutime));
80 processInfo.SetCumulativeSystemTime(convert(pstatusData.pr_cstime));
81 return true;
82}
83
84static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) {
85 struct psinfo psinfoData;
86 auto BufferOrError = getProcFile(pid, "psinfo");
87 if (!BufferOrError)
88 return false;
89
90 std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer = std::move(*BufferOrError);
91 // Ensure there's enough data for psinfoData
92 if (PsinfoBuffer->getBufferSize() < sizeof(psinfoData))
93 return false;
94
95 std::memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData));
96 llvm::StringRef PathRef(
97 psinfoData.pr_psargs,
98 strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs)));
99 if (PathRef.empty())
100 return false;
101
102 process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
103 ArchSpec arch_spec = ArchSpec();
104 arch_spec.SetArchitecture(eArchTypeXCOFF, llvm::XCOFF::TCPU_PPC64,
105 LLDB_INVALID_CPUTYPE, llvm::Triple::AIX);
106 process_info.SetArchitecture(arch_spec);
107 process_info.SetParentProcessID(psinfoData.pr_ppid);
108 process_info.SetGroupID(psinfoData.pr_gid);
109 process_info.SetEffectiveGroupID(psinfoData.pr_egid);
110 process_info.SetUserID(psinfoData.pr_uid);
111 process_info.SetEffectiveUserID(psinfoData.pr_euid);
112 process_info.SetProcessGroupID(psinfoData.pr_pgid);
113 process_info.SetProcessSessionID(psinfoData.pr_sid);
114 return true;
115}
116
118 ProcessInstanceInfo &process_info,
119 ProcessState &State) {
120 process_info.Clear();
121 process_info.SetProcessID(pid);
122
123 if (pid == LLDB_INVALID_PROCESS_ID)
124 return false;
125 // Get Executable path/Arch and Get User and Group IDs.
126 if (!GetExePathAndIds(pid, process_info))
127 return false;
128 // Get process status and timing info.
129 if (!GetStatusInfo(pid, process_info, State))
130 return false;
131
132 return true;
133}
134
136 ProcessInstanceInfoList &process_infos) {
137 static const char procdir[] = "/proc/";
138
139 DIR *dirproc = opendir(procdir);
140 if (dirproc) {
141 struct dirent *direntry = nullptr;
142 const uid_t our_uid = getuid();
143 const lldb::pid_t our_pid = getpid();
144 bool all_users = match_info.GetMatchAllUsers();
145
146 while ((direntry = readdir(dirproc)) != nullptr) {
147 lldb::pid_t pid;
148 // Skip non-numeric name directories
149 if (!llvm::to_integer(direntry->d_name, pid))
150 continue;
151 // Skip this process.
152 if (pid == our_pid)
153 continue;
154
155 ProcessState State;
156 ProcessInstanceInfo process_info;
157 if (!GetProcessAndStatInfo(pid, process_info, State))
158 continue;
159
160 if (State == ProcessState::Zombie ||
161 State == ProcessState::TracedOrStopped)
162 continue;
163
164 // Check for user match if we're not matching all users and not running
165 // as root.
166 if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
167 continue;
168
169 if (match_info.Matches(process_info))
170 process_infos.push_back(process_info);
171 }
172 closedir(dirproc);
173 }
174 return process_infos.size();
175}
176
178 ProcessState State;
179 return GetProcessAndStatInfo(pid, process_info, State);
180}
181
183 return Status("unimplemented");
184}
static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t)
Definition aix/Host.cpp:38
static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info)
Definition aix/Host.cpp:84
static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo, ProcessState &State)
Definition aix/Host.cpp:45
static bool GetProcessAndStatInfo(::pid_t pid, ProcessInstanceInfo &process_info, ProcessState &State)
Definition aix/Host.cpp:117
An architecture specification class.
Definition ArchSpec.h:31
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
Definition ArchSpec.cpp:836
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
static Status ShellExpandArguments(ProcessLaunchInfo &launch_info)
Perform expansion of the command-line for this launch info This can potentially involve wildcard expa...
Definition aix/Host.cpp:182
static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
Definition aix/Host.cpp:135
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition aix/Host.cpp:177
void SetGroupID(uint32_t gid)
Definition ProcessInfo.h:60
void SetArchitecture(const ArchSpec &arch)
Definition ProcessInfo.h:66
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:70
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:43
uint32_t GetUserID() const
Definition ProcessInfo.h:50
void SetUserID(uint32_t uid)
Definition ProcessInfo.h:58
bool Matches(const ProcessInstanceInfo &proc_info) const
void SetUserTime(struct timespec utime)
void SetEffectiveGroupID(uint32_t gid)
void SetIsZombie(bool is_zombie)
void SetCumulativeUserTime(struct timespec cutime)
void SetProcessGroupID(lldb::pid_t pgrp)
void SetProcessSessionID(lldb::pid_t session)
void SetCumulativeSystemTime(struct timespec cstime)
void SetSystemTime(struct timespec stime)
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
An error handling class.
Definition Status.h:118
#define LLDB_INVALID_CPUTYPE
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file)
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition Host.h:32
uint64_t pid_t
Definition lldb-types.h:83