Skip to content

Commit e7b3d8d

Browse files
committed
[lldb][AIX] get host info for AIX
1 parent 420c056 commit e7b3d8d

File tree

2 files changed

+156
-1
lines changed

2 files changed

+156
-1
lines changed

lldb/source/Host/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ else()
141141
add_host_subdirectory(aix
142142
aix/Host.cpp
143143
aix/HostInfoAIX.cpp
144+
linux/Support.cpp
144145
)
145146
endif()
146147
endif()

lldb/source/Host/aix/Host.cpp

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,172 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include <fcntl.h>
10+
#include <sstream>
11+
#include <sys/procfs.h>
12+
913
#include "lldb/Host/Host.h"
14+
#include "lldb/Host/linux/Support.h"
15+
#include "lldb/Utility/LLDBLog.h"
16+
#include "lldb/Utility/Log.h"
17+
#include "lldb/Utility/ProcessInfo.h"
1018
#include "lldb/Utility/Status.h"
19+
#include "llvm/BinaryFormat/XCOFF.h"
1120

21+
using namespace llvm;
22+
using namespace lldb;
1223
using namespace lldb_private;
1324

25+
namespace {
26+
enum class ProcessState {
27+
Unknown,
28+
Dead,
29+
DiskSleep,
30+
Idle,
31+
Paging,
32+
Parked,
33+
Running,
34+
Sleeping,
35+
TracedOrStopped,
36+
Zombie,
37+
};
38+
}
39+
40+
static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
41+
ProcessState &State, ::pid_t &TracerPid,
42+
::pid_t &Tgid) {
43+
Log *log = GetLog(LLDBLog::Host);
44+
45+
auto BufferOrError = getProcFile(Pid, "status");
46+
if (!BufferOrError)
47+
return false;
48+
49+
llvm::StringRef Rest = BufferOrError.get()->getBuffer();
50+
while (!Rest.empty()) {
51+
llvm::StringRef Line;
52+
std::tie(Line, Rest) = Rest.split('\n');
53+
54+
if (Line.consume_front("Gid:")) {
55+
// Real, effective, saved set, and file system GIDs. Read the first two.
56+
Line = Line.ltrim();
57+
uint32_t RGid, EGid;
58+
Line.consumeInteger(10, RGid);
59+
Line = Line.ltrim();
60+
Line.consumeInteger(10, EGid);
61+
62+
ProcessInfo.SetGroupID(RGid);
63+
ProcessInfo.SetEffectiveGroupID(EGid);
64+
} else if (Line.consume_front("Uid:")) {
65+
// Real, effective, saved set, and file system UIDs. Read the first two.
66+
Line = Line.ltrim();
67+
uint32_t RUid, EUid;
68+
Line.consumeInteger(10, RUid);
69+
Line = Line.ltrim();
70+
Line.consumeInteger(10, EUid);
71+
72+
ProcessInfo.SetUserID(RUid);
73+
ProcessInfo.SetEffectiveUserID(EUid);
74+
} else if (Line.consume_front("PPid:")) {
75+
::pid_t PPid;
76+
Line.ltrim().consumeInteger(10, PPid);
77+
ProcessInfo.SetParentProcessID(PPid);
78+
} else if (Line.consume_front("State:")) {
79+
State = llvm::StringSwitch<ProcessState>(Line.ltrim().take_front(1))
80+
.Case("D", ProcessState::DiskSleep)
81+
.Case("I", ProcessState::Idle)
82+
.Case("R", ProcessState::Running)
83+
.Case("S", ProcessState::Sleeping)
84+
.CaseLower("T", ProcessState::TracedOrStopped)
85+
.Case("W", ProcessState::Paging)
86+
.Case("P", ProcessState::Parked)
87+
.Case("X", ProcessState::Dead)
88+
.Case("Z", ProcessState::Zombie)
89+
.Default(ProcessState::Unknown);
90+
if (State == ProcessState::Unknown) {
91+
LLDB_LOG(log, "Unknown process state {0}", Line);
92+
}
93+
} else if (Line.consume_front("TracerPid:")) {
94+
Line = Line.ltrim();
95+
Line.consumeInteger(10, TracerPid);
96+
} else if (Line.consume_front("Tgid:")) {
97+
Line = Line.ltrim();
98+
Line.consumeInteger(10, Tgid);
99+
}
100+
}
101+
return true;
102+
}
103+
104+
static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
105+
Log *log = GetLog(LLDBLog::Process);
106+
std::string ExePath(PATH_MAX, '\0');
107+
struct psinfo psinfoData;
108+
109+
// We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
110+
llvm::SmallString<64> ProcExe;
111+
(llvm::Twine("/proc/") + llvm::Twine(pid) + "/cwd").toVector(ProcExe);
112+
113+
ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
114+
if (len > 0) {
115+
ExePath.resize(len);
116+
117+
struct stat statData;
118+
119+
std::ostringstream oss;
120+
121+
oss << "/proc/" << std::dec << pid << "/psinfo";
122+
assert(stat(oss.str().c_str(), &statData) == 0);
123+
124+
const int fd = open(oss.str().c_str(), O_RDONLY);
125+
assert(fd >= 0);
126+
127+
ssize_t readNum = read(fd, &psinfoData, sizeof(psinfoData));
128+
assert(readNum >= 0);
129+
130+
close(fd);
131+
} else {
132+
LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
133+
Status(errno, eErrorTypePOSIX));
134+
ExePath.resize(0);
135+
}
136+
137+
llvm::StringRef PathRef(&(psinfoData.pr_psargs[0]));
138+
139+
if (!PathRef.empty()) {
140+
process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
141+
ArchSpec arch_spec = ArchSpec();
142+
arch_spec.SetArchitecture(eArchTypeXCOFF, XCOFF::TCPU_PPC64,
143+
LLDB_INVALID_CPUTYPE, llvm::Triple::AIX);
144+
process_info.SetArchitecture(arch_spec);
145+
}
146+
}
147+
148+
static bool GetProcessAndStatInfo(::pid_t pid,
149+
ProcessInstanceInfo &process_info,
150+
ProcessState &State, ::pid_t &tracerpid) {
151+
::pid_t tgid;
152+
tracerpid = 0;
153+
process_info.Clear();
154+
155+
process_info.SetProcessID(pid);
156+
157+
GetExePathAndArch(pid, process_info);
158+
159+
// Get User and Group IDs and get tracer pid.
160+
if (!GetStatusInfo(pid, process_info, State, tracerpid, tgid))
161+
return false;
162+
163+
return true;
164+
}
165+
14166
uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
15167
ProcessInstanceInfoList &process_infos) {
16168
return 0;
17169
}
18170

19171
bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
20-
return false;
172+
::pid_t tracerpid;
173+
ProcessState State;
174+
return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
21175
}
22176

23177
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {

0 commit comments

Comments
 (0)