Skip to content

Commit 108831e

Browse files
HemangGadhavigoogle-yfyang
authored andcommitted
[lldb][AIX] get host info for AIX (cont..) (llvm#138687)
This PR is in reference to porting LLDB on AIX. Link to discussions on llvm discourse and github: 1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640 2. llvm#101657 The complete changes for porting are present in this draft PR: llvm#102601 - Added testcase for `GetProgramFileSpec()` & `FindProcesses()` - Added changes to get the host information for AIX (info like FindProcessesImpl() GetProgramFileSpec()), continue from the PR llvm#134354
1 parent 5b86108 commit 108831e

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

lldb/source/Host/aix/Host.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lldb/Utility/ProcessInfo.h"
1414
#include "lldb/Utility/Status.h"
1515
#include "llvm/BinaryFormat/XCOFF.h"
16+
#include <dirent.h>
1617
#include <sys/proc.h>
1718
#include <sys/procfs.h>
1819

@@ -133,7 +134,44 @@ static bool GetProcessAndStatInfo(::pid_t pid,
133134

134135
uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
135136
ProcessInstanceInfoList &process_infos) {
136-
return 0;
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();
137175
}
138176

139177
bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {

lldb/source/Host/aix/HostInfoAIX.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lldb/Host/aix/HostInfoAIX.h"
10+
#include "lldb/Host/posix/Support.h"
11+
#include <sys/procfs.h>
1012

1113
using namespace lldb_private;
1214

@@ -18,5 +20,17 @@ void HostInfoAIX::Terminate() { HostInfoBase::Terminate(); }
1820

1921
FileSpec HostInfoAIX::GetProgramFileSpec() {
2022
static FileSpec g_program_filespec;
23+
struct psinfo psinfoData;
24+
auto BufferOrError = getProcFile(getpid(), "psinfo");
25+
if (BufferOrError) {
26+
std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer =
27+
std::move(*BufferOrError);
28+
memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData));
29+
llvm::StringRef exe_path(
30+
psinfoData.pr_psargs,
31+
strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs)));
32+
if (!exe_path.empty())
33+
g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
34+
}
2135
return g_program_filespec;
2236
}

lldb/unittests/Host/HostInfoTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ TEST_F(HostInfoTest, GetHostname) {
5454
EXPECT_TRUE(HostInfo::GetHostname(s));
5555
}
5656

57+
TEST_F(HostInfoTest, GetProgramFileSpec) {
58+
FileSpec filespec = HostInfo::GetProgramFileSpec();
59+
EXPECT_TRUE(FileSystem::Instance().Exists(filespec));
60+
}
61+
5762
#if defined(__APPLE__)
5863
TEST_F(HostInfoTest, GetXcodeSDK) {
5964
auto get_sdk = [](std::string sdk, bool error = false) -> llvm::StringRef {

lldb/unittests/Host/HostTest.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@
99
#include "lldb/Host/Host.h"
1010
#include "TestingSupport/SubsystemRAII.h"
1111
#include "lldb/Host/FileSystem.h"
12+
#include "lldb/Host/HostInfo.h"
1213
#include "lldb/Host/Pipe.h"
1314
#include "lldb/Host/ProcessLaunchInfo.h"
1415
#include "lldb/Utility/ProcessInfo.h"
16+
#include "llvm/ADT/ScopeExit.h"
1517
#include "llvm/ADT/Twine.h"
1618
#include "llvm/Support/CommandLine.h"
1719
#include "llvm/Support/FileSystem.h"
1820
#include "llvm/Testing/Support/Error.h"
1921
#include "gtest/gtest.h"
2022
#include <future>
23+
#include <thread>
2124

2225
using namespace lldb_private;
2326
using namespace llvm;
@@ -90,6 +93,44 @@ TEST(Host, LaunchProcessSetsArgv0) {
9093
ASSERT_THAT(exit_status.get_future().get(), 0);
9194
}
9295

96+
TEST(Host, FindProcesses) {
97+
SubsystemRAII<FileSystem, HostInfo> subsystems;
98+
99+
if (test_arg != 0) {
100+
// Give the parent time to retrieve information about self.
101+
// It will kill self when it is done.
102+
std::this_thread::sleep_for(std::chrono::seconds(10));
103+
exit(0);
104+
}
105+
106+
bool foundPID = false;
107+
ProcessLaunchInfo info;
108+
ProcessInstanceInfoList processes;
109+
ProcessInstanceInfoMatch match(TestMainArgv0, NameMatch::Equals);
110+
info.SetExecutableFile(FileSpec(TestMainArgv0),
111+
/*add_exe_file_as_first_arg=*/true);
112+
info.GetArguments().AppendArgument("--gtest_filter=Host.FindProcesses");
113+
info.GetArguments().AppendArgument("--test-arg=48");
114+
std::promise<int> exit_status;
115+
info.SetMonitorProcessCallback([&](lldb::pid_t pid, int signal, int status) {
116+
exit_status.set_value(status);
117+
});
118+
ASSERT_THAT_ERROR(Host::LaunchProcess(info).takeError(), Succeeded());
119+
ASSERT_TRUE(Host::FindProcesses(match, processes));
120+
for (const auto &process : processes) {
121+
if (process.GetProcessID() == info.GetProcessID()) {
122+
ASSERT_EQ(process.GetExecutableFile().GetFilename(),
123+
info.GetExecutableFile().GetFilename());
124+
foundPID = true;
125+
}
126+
}
127+
ASSERT_TRUE(foundPID);
128+
auto clean_up = llvm::make_scope_exit([&] {
129+
Host::Kill(info.GetProcessID(), SIGKILL);
130+
exit_status.get_future().get();
131+
});
132+
}
133+
93134
TEST(Host, LaunchProcessDuplicatesHandle) {
94135
static constexpr llvm::StringLiteral test_msg("Hello subprocess!");
95136

0 commit comments

Comments
 (0)