Skip to content

Commit cc88649

Browse files
HemangGadhaviGeorgeARM
authored andcommitted
[lldb][AIX] get host info for AIX (llvm#134354)
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 changes to make the common host support functions under `Host/posix` for unix-like system. Also, created the `unittests/Host/posix/` to test the hostInfo & support functions for unix-like system. - Added changes to get the host information for AIX. (GetProcessInfo()) (Information like : executable path, arch, process status etc.)
1 parent 3da9e90 commit cc88649

File tree

16 files changed

+206
-46
lines changed

16 files changed

+206
-46
lines changed

lldb/include/lldb/Host/linux/Support.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ namespace lldb_private {
1818
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
1919
getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file);
2020

21-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
22-
getProcFile(::pid_t pid, const llvm::Twine &file);
23-
24-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
25-
getProcFile(const llvm::Twine &file);
26-
2721
} // namespace lldb_private
2822

2923
#endif // #ifndef LLDB_HOST_LINUX_SUPPORT_H
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- Support.h -----------------------------------------------*- 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+
#ifndef LLDB_HOST_POSIX_SUPPORT_H
10+
#define LLDB_HOST_POSIX_SUPPORT_H
11+
12+
#include "llvm/ADT/Twine.h"
13+
#include "llvm/Support/ErrorOr.h"
14+
#include "llvm/Support/MemoryBuffer.h"
15+
#include <memory>
16+
17+
namespace lldb_private {
18+
19+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
20+
getProcFile(::pid_t pid, const llvm::Twine &file);
21+
22+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
23+
getProcFile(const llvm::Twine &file);
24+
25+
} // namespace lldb_private
26+
27+
#endif // #ifndef LLDB_HOST_POSIX_SUPPORT_H

lldb/source/Host/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ else()
8787
posix/MainLoopPosix.cpp
8888
posix/PipePosix.cpp
8989
posix/ProcessLauncherPosixFork.cpp
90+
posix/Support.cpp
9091
)
9192

9293
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")

lldb/source/Host/aix/Host.cpp

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,138 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lldb/Host/Host.h"
10+
#include "lldb/Host/posix/Support.h"
11+
#include "lldb/Utility/LLDBLog.h"
12+
#include "lldb/Utility/Log.h"
13+
#include "lldb/Utility/ProcessInfo.h"
1014
#include "lldb/Utility/Status.h"
15+
#include "llvm/BinaryFormat/XCOFF.h"
16+
#include <sys/proc.h>
17+
#include <sys/procfs.h>
1118

19+
using namespace lldb;
1220
using namespace lldb_private;
1321

22+
namespace {
23+
enum class ProcessState {
24+
Unknown,
25+
Dead,
26+
DiskSleep,
27+
Idle,
28+
Paging,
29+
Parked,
30+
Running,
31+
Sleeping,
32+
TracedOrStopped,
33+
Zombie,
34+
};
35+
}
36+
37+
static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) {
38+
ProcessInstanceInfo::timespec ts;
39+
ts.tv_sec = t.tv_sec;
40+
ts.tv_usec = t.tv_nsec / 1000; // nanos to micros
41+
return ts;
42+
}
43+
44+
static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo,
45+
ProcessState &State) {
46+
struct pstatus pstatusData;
47+
auto BufferOrError = getProcFile(pid, "status");
48+
if (!BufferOrError)
49+
return false;
50+
51+
std::unique_ptr<llvm::MemoryBuffer> StatusBuffer = std::move(*BufferOrError);
52+
// Ensure there's enough data for psinfoData
53+
if (StatusBuffer->getBufferSize() < sizeof(pstatusData))
54+
return false;
55+
56+
std::memcpy(&pstatusData, StatusBuffer->getBufferStart(),
57+
sizeof(pstatusData));
58+
switch (pstatusData.pr_stat) {
59+
case SIDL:
60+
State = ProcessState::Idle;
61+
break;
62+
case SACTIVE:
63+
State = ProcessState::Running;
64+
break;
65+
case SSTOP:
66+
State = ProcessState::TracedOrStopped;
67+
break;
68+
case SZOMB:
69+
State = ProcessState::Zombie;
70+
break;
71+
default:
72+
State = ProcessState::Unknown;
73+
break;
74+
}
75+
processInfo.SetIsZombie(State == ProcessState::Zombie);
76+
processInfo.SetUserTime(convert(pstatusData.pr_utime));
77+
processInfo.SetSystemTime(convert(pstatusData.pr_stime));
78+
processInfo.SetCumulativeUserTime(convert(pstatusData.pr_cutime));
79+
processInfo.SetCumulativeSystemTime(convert(pstatusData.pr_cstime));
80+
return true;
81+
}
82+
83+
static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) {
84+
struct psinfo psinfoData;
85+
auto BufferOrError = getProcFile(pid, "psinfo");
86+
if (!BufferOrError)
87+
return false;
88+
89+
std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer = std::move(*BufferOrError);
90+
// Ensure there's enough data for psinfoData
91+
if (PsinfoBuffer->getBufferSize() < sizeof(psinfoData))
92+
return false;
93+
94+
std::memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData));
95+
llvm::StringRef PathRef(
96+
psinfoData.pr_psargs,
97+
strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs)));
98+
if (PathRef.empty())
99+
return false;
100+
101+
process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
102+
ArchSpec arch_spec = ArchSpec();
103+
arch_spec.SetArchitecture(eArchTypeXCOFF, llvm::XCOFF::TCPU_PPC64,
104+
LLDB_INVALID_CPUTYPE, llvm::Triple::AIX);
105+
process_info.SetArchitecture(arch_spec);
106+
process_info.SetParentProcessID(psinfoData.pr_ppid);
107+
process_info.SetGroupID(psinfoData.pr_gid);
108+
process_info.SetEffectiveGroupID(psinfoData.pr_egid);
109+
process_info.SetUserID(psinfoData.pr_uid);
110+
process_info.SetEffectiveUserID(psinfoData.pr_euid);
111+
process_info.SetProcessGroupID(psinfoData.pr_pgid);
112+
process_info.SetProcessSessionID(psinfoData.pr_sid);
113+
return true;
114+
}
115+
116+
static bool GetProcessAndStatInfo(::pid_t pid,
117+
ProcessInstanceInfo &process_info,
118+
ProcessState &State) {
119+
process_info.Clear();
120+
process_info.SetProcessID(pid);
121+
122+
if (pid == LLDB_INVALID_PROCESS_ID)
123+
return false;
124+
// Get Executable path/Arch and Get User and Group IDs.
125+
if (!GetExePathAndIds(pid, process_info))
126+
return false;
127+
// Get process status and timing info.
128+
if (!GetStatusInfo(pid, process_info, State))
129+
return false;
130+
131+
return true;
132+
}
133+
14134
uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
15135
ProcessInstanceInfoList &process_infos) {
16136
return 0;
17137
}
18138

19139
bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
20-
return false;
140+
ProcessState State;
141+
return GetProcessAndStatInfo(pid, process_info, State);
21142
}
22143

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

lldb/source/Host/linux/Host.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "lldb/Host/Host.h"
3131
#include "lldb/Host/HostInfo.h"
3232
#include "lldb/Host/linux/Host.h"
33-
#include "lldb/Host/linux/Support.h"
33+
#include "lldb/Host/posix/Support.h"
3434
#include "lldb/Utility/DataExtractor.h"
3535

3636
using namespace lldb;

lldb/source/Host/linux/Support.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,3 @@ lldb_private::getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file) {
2222
LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
2323
return Ret;
2424
}
25-
26-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
27-
lldb_private::getProcFile(::pid_t pid, const llvm::Twine &file) {
28-
Log *log = GetLog(LLDBLog::Host);
29-
std::string File = ("/proc/" + llvm::Twine(pid) + "/" + file).str();
30-
auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
31-
if (!Ret)
32-
LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
33-
return Ret;
34-
}
35-
36-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
37-
lldb_private::getProcFile(const llvm::Twine &file) {
38-
Log *log = GetLog(LLDBLog::Host);
39-
std::string File = ("/proc/" + file).str();
40-
auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
41-
if (!Ret)
42-
LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
43-
return Ret;
44-
}

lldb/source/Host/posix/Support.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-- Support.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/posix/Support.h"
10+
#include "lldb/Utility/LLDBLog.h"
11+
#include "lldb/Utility/Log.h"
12+
#include "llvm/Support/MemoryBuffer.h"
13+
14+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
15+
lldb_private::getProcFile(::pid_t pid, const llvm::Twine &file) {
16+
Log *log = GetLog(LLDBLog::Host);
17+
std::string File = ("/proc/" + llvm::Twine(pid) + "/" + file).str();
18+
auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
19+
if (!Ret)
20+
LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
21+
return Ret;
22+
}
23+
24+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
25+
lldb_private::getProcFile(const llvm::Twine &file) {
26+
Log *log = GetLog(LLDBLog::Host);
27+
std::string File = ("/proc/" + file).str();
28+
auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
29+
if (!Ret)
30+
LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
31+
return Ret;
32+
}

lldb/source/Plugins/Process/AIX/NativeProcessAIX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
1313
#include "lldb/Host/Debug.h"
1414
#include "lldb/Host/common/NativeProcessProtocol.h"
15-
#include "lldb/Host/linux/Support.h"
15+
#include "lldb/Host/posix/Support.h"
1616
#include "lldb/Target/MemoryRegionInfo.h"
1717
#include "lldb/Utility/ArchSpec.h"
1818
#include "lldb/Utility/FileSpec.h"

lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "Perf.h"
1111
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
1212
#include "Procfs.h"
13-
#include "lldb/Host/linux/Support.h"
1413
#include "lldb/Utility/StreamString.h"
1514
#include "llvm/ADT/StringRef.h"
1615
#include "llvm/Support/Error.h"

lldb/source/Plugins/Process/Linux/NativeProcessLinux.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "lldb/Host/Debug.h"
1616
#include "lldb/Host/HostThread.h"
1717
#include "lldb/Host/linux/Support.h"
18+
#include "lldb/Host/posix/Support.h"
1819
#include "lldb/Target/MemoryRegionInfo.h"
1920
#include "lldb/Utility/ArchSpec.h"
2021
#include "lldb/Utility/FileSpec.h"

lldb/source/Plugins/Process/Linux/Perf.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "Perf.h"
1010

1111
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
12-
#include "lldb/Host/linux/Support.h"
1312
#include "llvm/Support/FormatVariadic.h"
1413
#include "llvm/Support/MathExtras.h"
1514
#include "llvm/Support/MemoryBuffer.h"

lldb/source/Plugins/Process/Linux/Procfs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "Procfs.h"
10-
#include "lldb/Host/linux/Support.h"
10+
#include "lldb/Host/posix/Support.h"
1111
#include "llvm/ADT/StringExtras.h"
1212
#include "llvm/Support/Error.h"
1313
#include "llvm/Support/MemoryBuffer.h"

lldb/unittests/Host/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ set (FILES
1515
XMLTest.cpp
1616
)
1717

18-
if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
18+
if (UNIX)
1919
list(APPEND FILES
20-
linux/HostTest.cpp
21-
linux/SupportTest.cpp
20+
posix/HostTest.cpp
21+
posix/SupportTest.cpp
2222
)
2323
endif()
2424

lldb/unittests/Host/linux/HostTest.cpp renamed to lldb/unittests/Host/posix/HostTest.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ TEST_F(HostTest, GetProcessInfo) {
4040
triple.getEnvironment() == llvm::Triple::EnvironmentType::Android));
4141

4242
ProcessInstanceInfo Info;
43-
ASSERT_FALSE(Host::GetProcessInfo(0, Info));
43+
44+
ASSERT_FALSE(Host::GetProcessInfo(LLDB_INVALID_PROCESS_ID, Info));
4445

4546
ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
4647

@@ -90,6 +91,7 @@ TEST_F(HostTest, GetProcessInfo) {
9091
ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec ||
9192
user_time.tv_usec <= next_user_time.tv_usec);
9293

94+
#ifndef _AIX
9395
struct rlimit rlim;
9496
EXPECT_EQ(getrlimit(RLIMIT_NICE, &rlim), 0);
9597
// getpriority can return -1 so we zero errno first
@@ -108,4 +110,5 @@ TEST_F(HostTest, GetProcessInfo) {
108110
}
109111
ASSERT_TRUE(Info.IsZombie().has_value());
110112
ASSERT_FALSE(Info.IsZombie().value());
113+
#endif /* ifndef _AIX */
111114
}

lldb/unittests/Host/linux/SupportTest.cpp renamed to lldb/unittests/Host/posix/SupportTest.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,16 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "lldb/Host/linux/Support.h"
9+
#include "lldb/Host/posix/Support.h"
1010
#include "llvm/Support/Threading.h"
1111
#include "gtest/gtest.h"
1212

1313
using namespace lldb_private;
1414

15+
#ifndef __APPLE__
1516
TEST(Support, getProcFile_Pid) {
16-
auto BufferOrError = getProcFile(getpid(), "maps");
17+
auto BufferOrError = getProcFile(getpid(), "status");
1718
ASSERT_TRUE(BufferOrError);
1819
ASSERT_TRUE(*BufferOrError);
1920
}
20-
21-
#ifdef LLVM_ENABLE_THREADING
22-
TEST(Support, getProcFile_Tid) {
23-
auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm");
24-
ASSERT_TRUE(BufferOrError);
25-
ASSERT_TRUE(*BufferOrError);
26-
}
27-
#endif /*ifdef LLVM_ENABLE_THREADING */
21+
#endif // #ifndef __APPLE__

lldb/unittests/Process/Linux/ProcfsTests.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Procfs.h"
1010

1111
#include "lldb/Host/linux/Support.h"
12+
#include "lldb/Host/posix/Support.h"
1213

1314
#include "gmock/gmock.h"
1415
#include "gtest/gtest.h"
@@ -118,3 +119,11 @@ TEST(Perf, RealPtraceScope) {
118119
ASSERT_LE(*ptrace_scope, 3)
119120
<< "Sensible values of ptrace_scope are between 0 and 3";
120121
}
122+
123+
#ifdef LLVM_ENABLE_THREADING
124+
TEST(Support, getProcFile_Tid) {
125+
auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm");
126+
ASSERT_TRUE(BufferOrError);
127+
ASSERT_TRUE(*BufferOrError);
128+
}
129+
#endif /*ifdef LLVM_ENABLE_THREADING */

0 commit comments

Comments
 (0)