Skip to content

[lldb][AIX] get host info for AIX #134354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

HemangGadhavi
Copy link

@HemangGadhavi HemangGadhavi commented Apr 4, 2025

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. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #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.)
    @DavidSpickett @labath @DhruvSrivastavaX

Copy link

github-actions bot commented Apr 4, 2025

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added the lldb label Apr 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 4, 2025

@llvm/pr-subscribers-lldb

Author: Hemang Gadhavi (HemangGadhavi)

Changes

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. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #102601

Added changes to get the host information for AIX. (GetProcessInfo())
(Information like : executable path, arch, process status etc.)
@DavidSpickett @labath @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 --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) {

@DhruvSrivastavaX
Copy link
Contributor

DhruvSrivastavaX commented Apr 4, 2025

Hi Team,

@HemangGadhavi from our ibm aix team will be helping me out in some of the merging process, as per our decided guidelines. Please provide your review.

Thanks!
Dhruv Srivastava

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a tests for this function in unittests/Host/linux/HostTest.cpp and it looks like at least some of it should apply to other systems as well. We could move it to the "posix" folder so that it applies to your code as well. Depending on the size of linux-specific parts, we could either keep them in the "linux" folder, or #ifdef them out

@HemangGadhavi HemangGadhavi requested a review from labath April 10, 2025 11:48
Copy link

github-actions bot commented Apr 10, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@HemangGadhavi
Copy link
Author

HemangGadhavi commented Apr 10, 2025

We have a tests for this function in unittests/Host/linux/HostTest.cpp and it looks like at least some of it should apply to other systems as well. We could move it to the "posix" folder so that it applies to your code as well. Depending on the size of linux-specific parts, we could either keep them in the "linux" folder, or #ifdef them out

Okay, we will create new PR to either move it to posix or we can create HostTest.cpp for aix separately.
@labath or you want me to drop the testcase changes in same PR ?

@DhruvSrivastavaX
Copy link
Contributor

Please re-run clang-format on the changes.

@labath
Copy link
Collaborator

labath commented Apr 10, 2025

We have a tests for this function in unittests/Host/linux/HostTest.cpp and it looks like at least some of it should apply to other systems as well. We could move it to the "posix" folder so that it applies to your code as well. Depending on the size of linux-specific parts, we could either keep them in the "linux" folder, or #ifdef them out

Okay, we will create new PR to either move it to posix or we can create HostTest.cpp for aix separately. @labath or you want me to drop the testcase changes in same PR ?

Let's do that here. The PR is small (as it should be) and it's good to have tests together with the code being tested.

@HemangGadhavi
Copy link
Author

We have a tests for this function in unittests/Host/linux/HostTest.cpp and it looks like at least some of it should apply to other systems as well. We could move it to the "posix" folder so that it applies to your code as well. Depending on the size of linux-specific parts, we could either keep them in the "linux" folder, or #ifdef them out

Okay, we will create new PR to either move it to posix or we can create HostTest.cpp for aix separately. @labath or you want me to drop the testcase changes in same PR ?

Let's do that here. The PR is small (as it should be) and it's good to have tests together with the code being tested.

Hi @labath
I moved the unittests/Host/linux/HostTest.cpp & SupportTest.cpp under the unittests/Host/posix/, so that unix-like system can used it.
Also I have #ifdef out some of the tests, which are not applicable for AIX and tested on Linux/AIX all testcases are passed .
Please review it and give you comments.
Thanks

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good. Just a couple of details.

@HemangGadhavi
Copy link
Author

@labath Addressed all your comments, Please have a look once and give your comments if any.

@HemangGadhavi HemangGadhavi requested a review from labath April 23, 2025 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants