llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Hemang Gadhavi (HemangGadhavi) <details> <summary>Changes</summary> 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 get the host information for AIX. (GetProcessInfo()) (Information like : executable path, arch, process status etc.) [@<!-- -->DavidSpickett](https://github.com/DavidSpickett) [@<!-- -->labath](https://github.com/labath) [@<!-- -->DhruvSrivastavaX](https://github.com/DhruvSrivastavaX) --- Full diff: https://github.com/llvm/llvm-project/pull/134354.diff 2 Files Affected: - (modified) lldb/source/Host/CMakeLists.txt (+1) - (modified) lldb/source/Host/aix/Host.cpp (+155-1) ``````````diff diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index a2ae6f1430c38..a02b1c104396e 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -141,6 +141,7 @@ else() add_host_subdirectory(aix aix/Host.cpp aix/HostInfoAIX.cpp + linux/Support.cpp ) endif() endif() diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp index 751c4fbcc9368..6ba3e05348df1 100644 --- a/lldb/source/Host/aix/Host.cpp +++ b/lldb/source/Host/aix/Host.cpp @@ -6,18 +6,172 @@ // //===----------------------------------------------------------------------===// +#include <fcntl.h> +#include <sstream> +#include <sys/procfs.h> + #include "lldb/Host/Host.h" +#include "lldb/Host/linux/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" +using namespace llvm; +using namespace lldb; using namespace lldb_private; +namespace { +enum class ProcessState { + Unknown, + Dead, + DiskSleep, + Idle, + Paging, + Parked, + Running, + Sleeping, + TracedOrStopped, + Zombie, +}; +} + +static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, + ProcessState &State, ::pid_t &TracerPid, + ::pid_t &Tgid) { + Log *log = GetLog(LLDBLog::Host); + + auto BufferOrError = getProcFile(Pid, "status"); + if (!BufferOrError) + return false; + + llvm::StringRef Rest = BufferOrError.get()->getBuffer(); + while (!Rest.empty()) { + llvm::StringRef Line; + std::tie(Line, Rest) = Rest.split('\n'); + + if (Line.consume_front("Gid:")) { + // Real, effective, saved set, and file system GIDs. Read the first two. + Line = Line.ltrim(); + uint32_t RGid, EGid; + Line.consumeInteger(10, RGid); + Line = Line.ltrim(); + Line.consumeInteger(10, EGid); + + ProcessInfo.SetGroupID(RGid); + ProcessInfo.SetEffectiveGroupID(EGid); + } else if (Line.consume_front("Uid:")) { + // Real, effective, saved set, and file system UIDs. Read the first two. + Line = Line.ltrim(); + uint32_t RUid, EUid; + Line.consumeInteger(10, RUid); + Line = Line.ltrim(); + Line.consumeInteger(10, EUid); + + ProcessInfo.SetUserID(RUid); + ProcessInfo.SetEffectiveUserID(EUid); + } else if (Line.consume_front("PPid:")) { + ::pid_t PPid; + Line.ltrim().consumeInteger(10, PPid); + ProcessInfo.SetParentProcessID(PPid); + } else if (Line.consume_front("State:")) { + State = llvm::StringSwitch<ProcessState>(Line.ltrim().take_front(1)) + .Case("D", ProcessState::DiskSleep) + .Case("I", ProcessState::Idle) + .Case("R", ProcessState::Running) + .Case("S", ProcessState::Sleeping) + .CaseLower("T", ProcessState::TracedOrStopped) + .Case("W", ProcessState::Paging) + .Case("P", ProcessState::Parked) + .Case("X", ProcessState::Dead) + .Case("Z", ProcessState::Zombie) + .Default(ProcessState::Unknown); + if (State == ProcessState::Unknown) { + LLDB_LOG(log, "Unknown process state {0}", Line); + } + } else if (Line.consume_front("TracerPid:")) { + Line = Line.ltrim(); + Line.consumeInteger(10, TracerPid); + } else if (Line.consume_front("Tgid:")) { + Line = Line.ltrim(); + Line.consumeInteger(10, Tgid); + } + } + return true; +} + +static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) { + Log *log = GetLog(LLDBLog::Process); + std::string ExePath(PATH_MAX, '\0'); + struct psinfo psinfoData; + + // We can't use getProcFile here because proc/[pid]/exe is a symbolic link. + llvm::SmallString<64> ProcExe; + (llvm::Twine("/proc/") + llvm::Twine(pid) + "/cwd").toVector(ProcExe); + + ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX); + if (len > 0) { + ExePath.resize(len); + + struct stat statData; + + std::ostringstream oss; + + oss << "/proc/" << std::dec << pid << "/psinfo"; + assert(stat(oss.str().c_str(), &statData) == 0); + + const int fd = open(oss.str().c_str(), O_RDONLY); + assert(fd >= 0); + + ssize_t readNum = read(fd, &psinfoData, sizeof(psinfoData)); + assert(readNum >= 0); + + close(fd); + } else { + LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid, + Status(errno, eErrorTypePOSIX)); + ExePath.resize(0); + } + + llvm::StringRef PathRef(&(psinfoData.pr_psargs[0])); + + if (!PathRef.empty()) { + process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); + ArchSpec arch_spec = ArchSpec(); + arch_spec.SetArchitecture(eArchTypeXCOFF, XCOFF::TCPU_PPC64, + LLDB_INVALID_CPUTYPE, llvm::Triple::AIX); + process_info.SetArchitecture(arch_spec); + } +} + +static bool GetProcessAndStatInfo(::pid_t pid, + ProcessInstanceInfo &process_info, + ProcessState &State, ::pid_t &tracerpid) { + ::pid_t tgid; + tracerpid = 0; + process_info.Clear(); + + process_info.SetProcessID(pid); + + GetExePathAndArch(pid, process_info); + + // Get User and Group IDs and get tracer pid. + if (!GetStatusInfo(pid, process_info, State, tracerpid, tgid)) + 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; + ::pid_t tracerpid; + ProcessState State; + return GetProcessAndStatInfo(pid, process_info, State, tracerpid); } Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { `````````` </details> https://github.com/llvm/llvm-project/pull/134354 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits