Author: Hemang Gadhavi Date: 2025-04-29T11:23:03+05:30 New Revision: d1bb8d6a5c4a36490298ca75d144805179cc3b40
URL: https://github.com/llvm/llvm-project/commit/d1bb8d6a5c4a36490298ca75d144805179cc3b40 DIFF: https://github.com/llvm/llvm-project/commit/d1bb8d6a5c4a36490298ca75d144805179cc3b40.diff LOG: [lldb][AIX] get host info for AIX (#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. https://github.com/llvm/llvm-project/issues/101657 The complete changes for porting are present in this draft PR: https://github.com/llvm/llvm-project/pull/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.) Added: lldb/include/lldb/Host/posix/Support.h lldb/source/Host/posix/Support.cpp lldb/unittests/Host/posix/HostTest.cpp lldb/unittests/Host/posix/SupportTest.cpp Modified: lldb/include/lldb/Host/linux/Support.h lldb/source/Host/CMakeLists.txt lldb/source/Host/aix/Host.cpp lldb/source/Host/linux/Host.cpp lldb/source/Host/linux/Support.cpp lldb/source/Plugins/Process/AIX/NativeProcessAIX.h lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp lldb/source/Plugins/Process/Linux/NativeProcessLinux.h lldb/source/Plugins/Process/Linux/Perf.cpp lldb/source/Plugins/Process/Linux/Procfs.cpp lldb/unittests/Host/CMakeLists.txt lldb/unittests/Process/Linux/ProcfsTests.cpp Removed: lldb/unittests/Host/linux/HostTest.cpp lldb/unittests/Host/linux/SupportTest.cpp ################################################################################ diff --git a/lldb/include/lldb/Host/linux/Support.h b/lldb/include/lldb/Host/linux/Support.h index d1eb7f83d4916..1b8e1e2c26fa7 100644 --- a/lldb/include/lldb/Host/linux/Support.h +++ b/lldb/include/lldb/Host/linux/Support.h @@ -18,12 +18,6 @@ namespace lldb_private { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file); -llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -getProcFile(::pid_t pid, const llvm::Twine &file); - -llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -getProcFile(const llvm::Twine &file); - } // namespace lldb_private #endif // #ifndef LLDB_HOST_LINUX_SUPPORT_H diff --git a/lldb/include/lldb/Host/posix/Support.h b/lldb/include/lldb/Host/posix/Support.h new file mode 100644 index 0000000000000..4e779b6485ff4 --- /dev/null +++ b/lldb/include/lldb/Host/posix/Support.h @@ -0,0 +1,27 @@ +//===-- Support.h -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_HOST_POSIX_SUPPORT_H +#define LLDB_HOST_POSIX_SUPPORT_H + +#include "llvm/ADT/Twine.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include <memory> + +namespace lldb_private { + +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +getProcFile(::pid_t pid, const llvm::Twine &file); + +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +getProcFile(const llvm::Twine &file); + +} // namespace lldb_private + +#endif // #ifndef LLDB_HOST_POSIX_SUPPORT_H diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index a2ae6f1430c38..90814b1bed4c8 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -87,6 +87,7 @@ else() posix/MainLoopPosix.cpp posix/PipePosix.cpp posix/ProcessLauncherPosixFork.cpp + posix/Support.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Darwin") diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp index 751c4fbcc9368..a812e061ccae2 100644 --- a/lldb/source/Host/aix/Host.cpp +++ b/lldb/source/Host/aix/Host.cpp @@ -7,17 +7,138 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Host.h" +#include "lldb/Host/posix/Support.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Status.h" +#include "llvm/BinaryFormat/XCOFF.h" +#include <sys/proc.h> +#include <sys/procfs.h> +using namespace lldb; using namespace lldb_private; +namespace { +enum class ProcessState { + Unknown, + Dead, + DiskSleep, + Idle, + Paging, + Parked, + Running, + Sleeping, + TracedOrStopped, + Zombie, +}; +} + +static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) { + ProcessInstanceInfo::timespec ts; + ts.tv_sec = t.tv_sec; + ts.tv_usec = t.tv_nsec / 1000; // nanos to micros + return ts; +} + +static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo, + ProcessState &State) { + struct pstatus pstatusData; + auto BufferOrError = getProcFile(pid, "status"); + if (!BufferOrError) + return false; + + std::unique_ptr<llvm::MemoryBuffer> StatusBuffer = std::move(*BufferOrError); + // Ensure there's enough data for psinfoData + if (StatusBuffer->getBufferSize() < sizeof(pstatusData)) + return false; + + std::memcpy(&pstatusData, StatusBuffer->getBufferStart(), + sizeof(pstatusData)); + switch (pstatusData.pr_stat) { + case SIDL: + State = ProcessState::Idle; + break; + case SACTIVE: + State = ProcessState::Running; + break; + case SSTOP: + State = ProcessState::TracedOrStopped; + break; + case SZOMB: + State = ProcessState::Zombie; + break; + default: + State = ProcessState::Unknown; + break; + } + processInfo.SetIsZombie(State == ProcessState::Zombie); + processInfo.SetUserTime(convert(pstatusData.pr_utime)); + processInfo.SetSystemTime(convert(pstatusData.pr_stime)); + processInfo.SetCumulativeUserTime(convert(pstatusData.pr_cutime)); + processInfo.SetCumulativeSystemTime(convert(pstatusData.pr_cstime)); + return true; +} + +static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) { + struct psinfo psinfoData; + auto BufferOrError = getProcFile(pid, "psinfo"); + if (!BufferOrError) + return false; + + std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer = std::move(*BufferOrError); + // Ensure there's enough data for psinfoData + if (PsinfoBuffer->getBufferSize() < sizeof(psinfoData)) + return false; + + std::memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData)); + llvm::StringRef PathRef( + psinfoData.pr_psargs, + strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs))); + if (PathRef.empty()) + return false; + + process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); + ArchSpec arch_spec = ArchSpec(); + arch_spec.SetArchitecture(eArchTypeXCOFF, llvm::XCOFF::TCPU_PPC64, + LLDB_INVALID_CPUTYPE, llvm::Triple::AIX); + process_info.SetArchitecture(arch_spec); + process_info.SetParentProcessID(psinfoData.pr_ppid); + process_info.SetGroupID(psinfoData.pr_gid); + process_info.SetEffectiveGroupID(psinfoData.pr_egid); + process_info.SetUserID(psinfoData.pr_uid); + process_info.SetEffectiveUserID(psinfoData.pr_euid); + process_info.SetProcessGroupID(psinfoData.pr_pgid); + process_info.SetProcessSessionID(psinfoData.pr_sid); + return true; +} + +static bool GetProcessAndStatInfo(::pid_t pid, + ProcessInstanceInfo &process_info, + ProcessState &State) { + process_info.Clear(); + process_info.SetProcessID(pid); + + if (pid == LLDB_INVALID_PROCESS_ID) + return false; + // Get Executable path/Arch and Get User and Group IDs. + if (!GetExePathAndIds(pid, process_info)) + return false; + // Get process status and timing info. + if (!GetStatusInfo(pid, process_info, State)) + return false; + + return true; +} + uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { return 0; } bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { - return false; + ProcessState State; + return GetProcessAndStatInfo(pid, process_info, State); } Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 25bef9b0e7151..8b475a7ab5003 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -30,7 +30,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/linux/Host.h" -#include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "lldb/Utility/DataExtractor.h" using namespace lldb; diff --git a/lldb/source/Host/linux/Support.cpp b/lldb/source/Host/linux/Support.cpp index 8b0decc48c038..c6321e93f4dfa 100644 --- a/lldb/source/Host/linux/Support.cpp +++ b/lldb/source/Host/linux/Support.cpp @@ -22,23 +22,3 @@ lldb_private::getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file) { LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message()); return Ret; } - -llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -lldb_private::getProcFile(::pid_t pid, const llvm::Twine &file) { - Log *log = GetLog(LLDBLog::Host); - std::string File = ("/proc/" + llvm::Twine(pid) + "/" + file).str(); - auto Ret = llvm::MemoryBuffer::getFileAsStream(File); - if (!Ret) - LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message()); - return Ret; -} - -llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -lldb_private::getProcFile(const llvm::Twine &file) { - Log *log = GetLog(LLDBLog::Host); - std::string File = ("/proc/" + file).str(); - auto Ret = llvm::MemoryBuffer::getFileAsStream(File); - if (!Ret) - LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message()); - return Ret; -} diff --git a/lldb/source/Host/posix/Support.cpp b/lldb/source/Host/posix/Support.cpp new file mode 100644 index 0000000000000..abfcc8ddb2d7f --- /dev/null +++ b/lldb/source/Host/posix/Support.cpp @@ -0,0 +1,32 @@ +//===-- Support.cpp -------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/posix/Support.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "llvm/Support/MemoryBuffer.h" + +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +lldb_private::getProcFile(::pid_t pid, const llvm::Twine &file) { + Log *log = GetLog(LLDBLog::Host); + std::string File = ("/proc/" + llvm::Twine(pid) + "/" + file).str(); + auto Ret = llvm::MemoryBuffer::getFileAsStream(File); + if (!Ret) + LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message()); + return Ret; +} + +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +lldb_private::getProcFile(const llvm::Twine &file) { + Log *log = GetLog(LLDBLog::Host); + std::string File = ("/proc/" + file).str(); + auto Ret = llvm::MemoryBuffer::getFileAsStream(File); + if (!Ret) + LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message()); + return Ret; +} diff --git a/lldb/source/Plugins/Process/AIX/NativeProcessAIX.h b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.h index 0fd7ff2785123..bc44f2b02af98 100644 --- a/lldb/source/Plugins/Process/AIX/NativeProcessAIX.h +++ b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.h @@ -12,7 +12,7 @@ #include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h" #include "lldb/Host/Debug.h" #include "lldb/Host/common/NativeProcessProtocol.h" -#include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" diff --git a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp index a38b75c9e615f..06551a4ff5a00 100644 --- a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp +++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp @@ -10,7 +10,6 @@ #include "Perf.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Procfs.h" -#include "lldb/Host/linux/Support.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 2af6c646332c9..d345f165a75d8 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -15,6 +15,7 @@ #include "lldb/Host/Debug.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" diff --git a/lldb/source/Plugins/Process/Linux/Perf.cpp b/lldb/source/Plugins/Process/Linux/Perf.cpp index 097c719b9c1d2..4207364812110 100644 --- a/lldb/source/Plugins/Process/Linux/Perf.cpp +++ b/lldb/source/Plugins/Process/Linux/Perf.cpp @@ -9,7 +9,6 @@ #include "Perf.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Host/linux/Support.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/lldb/source/Plugins/Process/Linux/Procfs.cpp b/lldb/source/Plugins/Process/Linux/Procfs.cpp index 8c279c7ab6533..d3bd396fbaeab 100644 --- a/lldb/source/Plugins/Process/Linux/Procfs.cpp +++ b/lldb/source/Plugins/Process/Linux/Procfs.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "Procfs.h" -#include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/lldb/unittests/Host/CMakeLists.txt b/lldb/unittests/Host/CMakeLists.txt index c959478970d18..5b8deed00af88 100644 --- a/lldb/unittests/Host/CMakeLists.txt +++ b/lldb/unittests/Host/CMakeLists.txt @@ -15,10 +15,10 @@ set (FILES XMLTest.cpp ) -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if (UNIX) list(APPEND FILES - linux/HostTest.cpp - linux/SupportTest.cpp + posix/HostTest.cpp + posix/SupportTest.cpp ) endif() diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/posix/HostTest.cpp similarity index 97% rename from lldb/unittests/Host/linux/HostTest.cpp rename to lldb/unittests/Host/posix/HostTest.cpp index d6aefcc7faa25..b4b3a33e7ddc1 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/posix/HostTest.cpp @@ -40,7 +40,8 @@ TEST_F(HostTest, GetProcessInfo) { triple.getEnvironment() == llvm::Triple::EnvironmentType::Android)); ProcessInstanceInfo Info; - ASSERT_FALSE(Host::GetProcessInfo(0, Info)); + + ASSERT_FALSE(Host::GetProcessInfo(LLDB_INVALID_PROCESS_ID, Info)); ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); @@ -90,6 +91,7 @@ TEST_F(HostTest, GetProcessInfo) { ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || user_time.tv_usec <= next_user_time.tv_usec); +#ifndef _AIX struct rlimit rlim; EXPECT_EQ(getrlimit(RLIMIT_NICE, &rlim), 0); // getpriority can return -1 so we zero errno first @@ -108,4 +110,5 @@ TEST_F(HostTest, GetProcessInfo) { } ASSERT_TRUE(Info.IsZombie().has_value()); ASSERT_FALSE(Info.IsZombie().value()); +#endif /* ifndef _AIX */ } diff --git a/lldb/unittests/Host/linux/SupportTest.cpp b/lldb/unittests/Host/posix/SupportTest.cpp similarity index 62% rename from lldb/unittests/Host/linux/SupportTest.cpp rename to lldb/unittests/Host/posix/SupportTest.cpp index 6d1d28cd4caad..f3976db755943 100644 --- a/lldb/unittests/Host/linux/SupportTest.cpp +++ b/lldb/unittests/Host/posix/SupportTest.cpp @@ -6,22 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "llvm/Support/Threading.h" #include "gtest/gtest.h" using namespace lldb_private; +#ifndef __APPLE__ TEST(Support, getProcFile_Pid) { - auto BufferOrError = getProcFile(getpid(), "maps"); + auto BufferOrError = getProcFile(getpid(), "status"); ASSERT_TRUE(BufferOrError); ASSERT_TRUE(*BufferOrError); } - -#ifdef LLVM_ENABLE_THREADING -TEST(Support, getProcFile_Tid) { - auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm"); - ASSERT_TRUE(BufferOrError); - ASSERT_TRUE(*BufferOrError); -} -#endif /*ifdef LLVM_ENABLE_THREADING */ +#endif // #ifndef __APPLE__ diff --git a/lldb/unittests/Process/Linux/ProcfsTests.cpp b/lldb/unittests/Process/Linux/ProcfsTests.cpp index d95de649ed578..e7af1f469c2bf 100644 --- a/lldb/unittests/Process/Linux/ProcfsTests.cpp +++ b/lldb/unittests/Process/Linux/ProcfsTests.cpp @@ -9,6 +9,7 @@ #include "Procfs.h" #include "lldb/Host/linux/Support.h" +#include "lldb/Host/posix/Support.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -118,3 +119,11 @@ TEST(Perf, RealPtraceScope) { ASSERT_LE(*ptrace_scope, 3) << "Sensible values of ptrace_scope are between 0 and 3"; } + +#ifdef LLVM_ENABLE_THREADING +TEST(Support, getProcFile_Tid) { + auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm"); + ASSERT_TRUE(BufferOrError); + ASSERT_TRUE(*BufferOrError); +} +#endif /*ifdef LLVM_ENABLE_THREADING */ _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits