Skip to content

[lldb][AIX] get host info for AIX (cont..) #138687

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 5 commits into
base: main
Choose a base branch
from

Conversation

HemangGadhavi
Copy link
Contributor

@HemangGadhavi HemangGadhavi commented May 6, 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

@llvmbot llvmbot added the lldb label May 6, 2025
@llvmbot
Copy link
Member

llvmbot commented May 6, 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

Full diff: https://github.com/llvm/llvm-project/pull/138687.diff

2 Files Affected:

  • (modified) lldb/source/Host/aix/Host.cpp (+48-1)
  • (modified) lldb/source/Host/aix/HostInfoAIX.cpp (+15)
diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp
index a812e061ccae2..ead8202cbbdef 100644
--- a/lldb/source/Host/aix/Host.cpp
+++ b/lldb/source/Host/aix/Host.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Utility/ProcessInfo.h"
 #include "lldb/Utility/Status.h"
 #include "llvm/BinaryFormat/XCOFF.h"
+#include <dirent.h>
 #include <sys/proc.h>
 #include <sys/procfs.h>
 
@@ -41,6 +42,14 @@ static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) {
   return ts;
 }
 
+static bool IsDirNumeric(const char *dname) {
+  for (; *dname; dname++) {
+    if (!isdigit(*dname))
+      return false;
+  }
+  return true;
+}
+
 static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo,
                           ProcessState &State) {
   struct pstatus pstatusData;
@@ -133,7 +142,45 @@ static bool GetProcessAndStatInfo(::pid_t pid,
 
 uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
                                  ProcessInstanceInfoList &process_infos) {
-  return 0;
+  static const char procdir[] = "/proc/";
+
+  DIR *dirproc = opendir(procdir);
+  if (dirproc) {
+    struct dirent *direntry = nullptr;
+    const uid_t our_uid = getuid();
+    const lldb::pid_t our_pid = getpid();
+    bool all_users = match_info.GetMatchAllUsers();
+
+    while ((direntry = readdir(dirproc)) != nullptr) {
+      if (!IsDirNumeric(direntry->d_name))
+        continue;
+
+      lldb::pid_t pid = atoi(direntry->d_name);
+      // Skip this process.
+      if (pid == our_pid)
+        continue;
+
+      ProcessState State;
+      ProcessInstanceInfo process_info;
+      if (!GetProcessAndStatInfo(pid, process_info, State))
+        continue;
+
+      if (State == ProcessState::Zombie ||
+          State == ProcessState::TracedOrStopped)
+        continue;
+
+      // Check for user match if we're not matching all users and not running
+      // as root.
+      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
+        continue;
+
+      if (match_info.Matches(process_info)) {
+        process_infos.push_back(process_info);
+      }
+    }
+    closedir(dirproc);
+  }
+  return process_infos.size();
 }
 
 bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
diff --git a/lldb/source/Host/aix/HostInfoAIX.cpp b/lldb/source/Host/aix/HostInfoAIX.cpp
index 61b47462dd647..d720f5c52d3b1 100644
--- a/lldb/source/Host/aix/HostInfoAIX.cpp
+++ b/lldb/source/Host/aix/HostInfoAIX.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Host/aix/HostInfoAIX.h"
+#include "lldb/Host/posix/Support.h"
+#include <sys/procfs.h>
 
 using namespace lldb_private;
 
@@ -18,5 +20,18 @@ void HostInfoAIX::Terminate() { HostInfoBase::Terminate(); }
 
 FileSpec HostInfoAIX::GetProgramFileSpec() {
   static FileSpec g_program_filespec;
+  struct psinfo psinfoData;
+  auto BufferOrError = getProcFile(getpid(), "psinfo");
+  if (BufferOrError) {
+    std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer =
+        std::move(*BufferOrError);
+    memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData));
+    llvm::StringRef exe_path(
+        psinfoData.pr_psargs,
+        strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs)));
+    if (!exe_path.empty()) {
+      g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
+    }
+  }
   return g_program_filespec;
 }

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.

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

@HemangGadhavi
Copy link
Contributor Author

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

Hi @labath
Created the testcases for the GetProgramFileSpec & FindProcesses.

But for the FindProcesses() testcase, we are able to launch the process but later point we are seeing dump on the testcase.
Could you please verify are we giving the input correctly or missing something?
from the logs we can see that GetProcessAndStatInfo() (which is invoked from GetProcessInfo() & FindProcesses()) dumping the core specifically while calling GetExePathAndArch() function on linux.
Could you please help to guide on that.?

@HemangGadhavi HemangGadhavi requested a review from labath May 21, 2025 09:36
@labath
Copy link
Collaborator

labath commented May 21, 2025

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

Hi @labath Created the testcases for the GetProgramFileSpec & FindProcesses.

But for the FindProcesses() testcase, we are able to launch the process but later point we are seeing dump on the testcase. Could you please verify are we giving the input correctly or missing something? from the logs we can see that GetProcessAndStatInfo() (which is invoked from GetProcessInfo() & FindProcesses()) dumping the core specifically while calling GetExePathAndArch() function on linux. Could you please help to guide on that.?

I'll take a look. I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

@labath
Copy link
Collaborator

labath commented May 21, 2025

The failure is in lldb_private::HostInfoBase::GetArchitecture. To fix this, you need to Initialize() the HostInfo class.

@HemangGadhavi
Copy link
Contributor Author

The failure is in lldb_private::HostInfoBase::GetArchitecture. To fix this, you need to Initialize() the HostInfo class.

Thank you @labath. Thanks for the guidance, it worked.
Could you please review and give your comments.

@HemangGadhavi HemangGadhavi requested a review from labath May 22, 2025 11:52
@labath
Copy link
Collaborator

labath commented May 23, 2025

I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

The code looks good, but you still need to do something to ensure there's no race in retrieving the process info.

@HemangGadhavi
Copy link
Contributor Author

I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

The code looks good, but you still need to do something to ensure there's no race in retrieving the process info.

Hi @labath Added some delay which gives some time before retrieving the process info.
Please review once.

@DhruvSrivastavaX
Copy link
Contributor

Side-Note: @HemangGadhavi Please verify that these pass on our AIX setup as well.

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