Skip to content

[lldb] Expose SBPlatform::GetAllProcesses to the SB API #68378

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

Merged

Conversation

JDevlieghere
Copy link
Member

Add the ability to list all processes through the SB API.

rdar://116188959

@llvmbot
Copy link
Member

llvmbot commented Oct 6, 2023

@llvm/pr-subscribers-lldb

Changes

Add the ability to list all processes through the SB API.

rdar://116188959


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

15 Files Affected:

  • (modified) lldb/bindings/headers.swig (+1)
  • (added) lldb/bindings/interface/SBProcessInfoListExtensions.i (+13)
  • (modified) lldb/bindings/interfaces.swig (+2)
  • (modified) lldb/include/lldb/API/LLDB.h (+1)
  • (modified) lldb/include/lldb/API/SBDefines.h (+1)
  • (modified) lldb/include/lldb/API/SBPlatform.h (+4)
  • (modified) lldb/include/lldb/API/SBProcessInfo.h (+1)
  • (added) lldb/include/lldb/API/SBProcessInfoList.h (+46)
  • (modified) lldb/include/lldb/Target/Platform.h (+3-1)
  • (modified) lldb/include/lldb/Utility/ProcessInfo.h (+20)
  • (modified) lldb/source/API/CMakeLists.txt (+1)
  • (modified) lldb/source/API/SBPlatform.cpp (+15)
  • (added) lldb/source/API/SBProcessInfoList.cpp (+73)
  • (modified) lldb/source/Target/Platform.cpp (+8)
  • (added) lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py (+54)
diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig
index d392ed43d8c0c9e..b1d88726f754354 100644
--- a/lldb/bindings/headers.swig
+++ b/lldb/bindings/headers.swig
@@ -46,6 +46,7 @@
 #include "lldb/API/SBPlatform.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBProcessInfo.h"
+#include "lldb/API/SBProcessInfoList.h"
 #include "lldb/API/SBQueue.h"
 #include "lldb/API/SBQueueItem.h"
 #include "lldb/API/SBReproducer.h"
diff --git a/lldb/bindings/interface/SBProcessInfoListExtensions.i b/lldb/bindings/interface/SBProcessInfoListExtensions.i
new file mode 100644
index 000000000000000..42999846ef6a52f
--- /dev/null
+++ b/lldb/bindings/interface/SBProcessInfoListExtensions.i
@@ -0,0 +1,13 @@
+%extend lldb::SBProcessInfoList {
+#ifdef SWIGPYTHON
+    %pythoncode%{
+    def __len__(self):
+      '''Return the number of process info in a lldb.SBProcessInfoListExtensions object.'''
+      return self.GetSize()
+
+    def __iter__(self):
+      '''Iterate over all the process info in a lldb.SBProcessInfoListExtensions object.'''
+      return lldb_iter(self, 'GetSize', 'GetProcessInfoAtIndex')
+    %}
+#endif
+}
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 306cfe683893271..373c2f6cf545cfb 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -122,6 +122,7 @@
 %include "lldb/API/SBPlatform.h"
 %include "lldb/API/SBProcess.h"
 %include "lldb/API/SBProcessInfo.h"
+%include "lldb/API/SBProcessInfoList.h"
 %include "lldb/API/SBQueue.h"
 %include "lldb/API/SBQueueItem.h"
 %include "lldb/API/SBReproducer.h"
@@ -184,6 +185,7 @@
 %include "./interface/SBModuleSpecExtensions.i"
 %include "./interface/SBModuleSpecListExtensions.i"
 %include "./interface/SBProcessExtensions.i"
+%include "./interface/SBProcessInfoListExtensions.i"
 %include "./interface/SBQueueItemExtensions.i"
 %include "./interface/SBScriptObjectExtensions.i"
 %include "./interface/SBSectionExtensions.i"
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index eacbbeafcf1cd86..f652d1bdb835b59 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -49,6 +49,7 @@
 #include "lldb/API/SBPlatform.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBProcessInfo.h"
+#include "lldb/API/SBProcessInfoList.h"
 #include "lldb/API/SBQueue.h"
 #include "lldb/API/SBQueueItem.h"
 #include "lldb/API/SBReproducer.h"
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index ec5e940fdaf36fc..c6f01cc03f263c8 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -90,6 +90,7 @@ class LLDB_API SBPlatformConnectOptions;
 class LLDB_API SBPlatformShellCommand;
 class LLDB_API SBProcess;
 class LLDB_API SBProcessInfo;
+class LLDB_API SBProcessInfoList;
 class LLDB_API SBQueue;
 class LLDB_API SBQueueItem;
 class LLDB_API SBReplayOptions;
diff --git a/lldb/include/lldb/API/SBPlatform.h b/lldb/include/lldb/API/SBPlatform.h
index e0acc7003a54bc3..d63d2ed1eaba627 100644
--- a/lldb/include/lldb/API/SBPlatform.h
+++ b/lldb/include/lldb/API/SBPlatform.h
@@ -11,11 +11,13 @@
 
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBProcess.h"
+#include "lldb/API/SBProcessInfoList.h"
 
 #include <functional>
 
 struct PlatformConnectOptions;
 struct PlatformShellCommand;
+class ProcessInstanceInfoMatch;
 
 namespace lldb {
 
@@ -154,6 +156,8 @@ class LLDB_API SBPlatform {
   SBProcess Attach(SBAttachInfo &attach_info, const SBDebugger &debugger,
                    SBTarget &target, SBError &error);
 
+  SBProcessInfoList GetAllProcesses(SBError &error);
+
   SBError Kill(const lldb::pid_t pid);
 
   SBError
diff --git a/lldb/include/lldb/API/SBProcessInfo.h b/lldb/include/lldb/API/SBProcessInfo.h
index 36fae9e842a6136..aec5924e4704a49 100644
--- a/lldb/include/lldb/API/SBProcessInfo.h
+++ b/lldb/include/lldb/API/SBProcessInfo.h
@@ -55,6 +55,7 @@ class LLDB_API SBProcessInfo {
 
 private:
   friend class SBProcess;
+  friend class SBProcessInfoList;
 
   lldb_private::ProcessInstanceInfo &ref();
 
diff --git a/lldb/include/lldb/API/SBProcessInfoList.h b/lldb/include/lldb/API/SBProcessInfoList.h
new file mode 100644
index 000000000000000..7591fb3db713874
--- /dev/null
+++ b/lldb/include/lldb/API/SBProcessInfoList.h
@@ -0,0 +1,46 @@
+//===-- SBProcessInfoList.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_API_SBPROCESSINSTANCEINFOLIST_H
+#define LLDB_API_SBPROCESSINSTANCEINFOLIST_H
+
+#include "lldb/API/SBDefines.h"
+
+#include <memory>
+
+namespace lldb_private {
+class ProcessInfoList;
+} // namespace lldb_private
+
+namespace lldb {
+
+class LLDB_API SBProcessInfoList {
+public:
+  SBProcessInfoList();
+  ~SBProcessInfoList();
+
+  SBProcessInfoList(const lldb::SBProcessInfoList &rhs);
+
+  const lldb::SBProcessInfoList &operator=(const lldb::SBProcessInfoList &rhs);
+
+  uint32_t GetSize() const;
+
+  bool GetProcessInfoAtIndex(uint32_t idx, SBProcessInfo &info);
+
+  void Clear();
+
+private:
+  friend SBPlatform;
+
+  SBProcessInfoList(const lldb_private::ProcessInfoList &impl);
+  std::unique_ptr<lldb_private::ProcessInfoList> m_opaque_up;
+};
+
+} // namespace lldb
+
+#endif // LLDB_API_SBPROCESSINSTANCEINFOLIST_H
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 08a58c80ef84779..129e4565d9ff993 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -407,6 +407,8 @@ class Platform : public PluginInterface {
   virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
                                  ProcessInstanceInfoList &proc_infos);
 
+  ProcessInstanceInfoList GetAllProcesses();
+
   virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info);
 
   // Set a breakpoint on all functions that can end up creating a thread for
@@ -883,7 +885,7 @@ class Platform : public PluginInterface {
   }
 
   virtual CompilerType GetSiginfoType(const llvm::Triple &triple);
-  
+
   virtual Args GetExtraStartupCommands();
 
   typedef std::function<Status(const ModuleSpec &module_spec,
diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h
index f56b30ab82ec669..7fb5b37be0f48f1 100644
--- a/lldb/include/lldb/Utility/ProcessInfo.h
+++ b/lldb/include/lldb/Utility/ProcessInfo.h
@@ -187,6 +187,26 @@ class ProcessInstanceInfo : public ProcessInfo {
 
 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
 
+class ProcessInfoList {
+public:
+  ProcessInfoList(const ProcessInstanceInfoList &list) : m_list(list) {}
+
+  uint32_t GetSize() const { return m_list.size(); }
+
+  bool GetProcessInfoAtIndex(uint32_t idx, ProcessInstanceInfo &info) {
+    if (idx < m_list.size()) {
+      info = m_list[idx];
+      return true;
+    }
+    return false;
+  }
+
+  void Clear() { return m_list.clear(); }
+
+private:
+  ProcessInstanceInfoList m_list;
+};
+
 // ProcessInstanceInfoMatch
 //
 // A class to help matching one ProcessInstanceInfo to another.
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index 7cfa3aaafdae188..fb10d764be02c94 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -61,6 +61,7 @@ add_lldb_library(liblldb SHARED ${option_framework}
   SBPlatform.cpp
   SBProcess.cpp
   SBProcessInfo.cpp
+  SBProcessInfoList.cpp
   SBQueue.cpp
   SBQueueItem.cpp
   SBReproducer.cpp
diff --git a/lldb/source/API/SBPlatform.cpp b/lldb/source/API/SBPlatform.cpp
index c31848fe04ea72c..3623fd35bcdf13f 100644
--- a/lldb/source/API/SBPlatform.cpp
+++ b/lldb/source/API/SBPlatform.cpp
@@ -14,6 +14,7 @@
 #include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBModuleSpec.h"
 #include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBProcessInfoList.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBUnixSignals.h"
 #include "lldb/Host/File.h"
@@ -599,6 +600,20 @@ SBProcess SBPlatform::Attach(SBAttachInfo &attach_info,
   return {};
 }
 
+SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) {
+  if (PlatformSP platform_sp = GetSP()) {
+    if (platform_sp->IsConnected()) {
+      ProcessInstanceInfoList list = platform_sp->GetAllProcesses();
+      return SBProcessInfoList(list);
+    }
+    error.SetErrorString("not connected");
+    return {};
+  }
+
+  error.SetErrorString("invalid platform");
+  return {};
+}
+
 SBError SBPlatform::Kill(const lldb::pid_t pid) {
   LLDB_INSTRUMENT_VA(this, pid);
   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
diff --git a/lldb/source/API/SBProcessInfoList.cpp b/lldb/source/API/SBProcessInfoList.cpp
new file mode 100644
index 000000000000000..a4d1e353f27d90e
--- /dev/null
+++ b/lldb/source/API/SBProcessInfoList.cpp
@@ -0,0 +1,73 @@
+//===-- SBProcessInfoList.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/API/SBProcessInfoList.h"
+#include "Utils.h"
+#include "lldb/API/SBProcessInfo.h"
+#include "lldb/Utility/Instrumentation.h"
+#include "lldb/Utility/ProcessInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBProcessInfoList::SBProcessInfoList() = default;
+
+SBProcessInfoList::~SBProcessInfoList() = default;
+
+SBProcessInfoList::SBProcessInfoList(const ProcessInfoList &impl)
+    : m_opaque_up(std::make_unique<ProcessInfoList>(impl)) {
+  LLDB_INSTRUMENT_VA(this, impl);
+}
+
+SBProcessInfoList::SBProcessInfoList(const lldb::SBProcessInfoList &rhs) {
+
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  m_opaque_up = clone(rhs.m_opaque_up);
+}
+
+const lldb::SBProcessInfoList &
+SBProcessInfoList::operator=(const lldb::SBProcessInfoList &rhs) {
+
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  if (this != &rhs)
+    m_opaque_up = clone(rhs.m_opaque_up);
+  return *this;
+}
+
+uint32_t SBProcessInfoList::GetSize() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  if (m_opaque_up)
+    return m_opaque_up->GetSize();
+
+  return 0;
+}
+
+void SBProcessInfoList::Clear() {
+  LLDB_INSTRUMENT_VA(this);
+
+  if (m_opaque_up)
+    m_opaque_up->Clear();
+}
+
+bool SBProcessInfoList::GetProcessInfoAtIndex(uint32_t idx,
+                                              SBProcessInfo &info) {
+  LLDB_INSTRUMENT_VA(this, idx, info);
+
+  if (m_opaque_up) {
+    lldb_private::ProcessInstanceInfo process_instance_info;
+    if (m_opaque_up->GetProcessInfoAtIndex(idx, process_instance_info)) {
+      info.SetProcessInfo(process_instance_info);
+      return true;
+    }
+  }
+
+  return false;
+}
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index c117339f07cc9df..c345e33136070f2 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -989,6 +989,14 @@ uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
   return match_count;
 }
 
+ProcessInstanceInfoList Platform::GetAllProcesses() {
+  ProcessInstanceInfoList processes;
+  ProcessInstanceInfoMatch match;
+  assert(match.MatchAllProcesses());
+  FindProcesses(match, processes);
+  return processes;
+}
+
 Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
   Status error;
   Log *log = GetLog(LLDBLog::Platform);
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py
new file mode 100644
index 000000000000000..be0e3f5f8c50112
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py
@@ -0,0 +1,54 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
+
+
+class TestPlatformListProcesses(GDBRemoteTestBase):
+    @skipIfRemote
+    @skipIfWindows
+    def test_get_all_processes(self):
+        """Test listing processes"""
+
+        class MyPlatformResponder(MockGDBServerResponder):
+            def __init__(self):
+                MockGDBServerResponder.__init__(self)
+                self.done = False
+
+            def qfProcessInfo(self, packet):
+                return "pid:95117;name:666f6f;"
+
+            def qsProcessInfo(self):
+                if not self.done:
+                    self.done = True
+                    return "pid:95126;name:666f6f;"
+                return "E10"
+
+        self.server.responder = MyPlatformResponder()
+
+        error = lldb.SBError()
+        platform = lldb.SBPlatform("remote-linux")
+        self.dbg.SetSelectedPlatform(platform)
+
+        error = platform.ConnectRemote(
+            lldb.SBPlatformConnectOptions(self.server.get_connect_url())
+        )
+        self.assertSuccess(error)
+        self.assertTrue(platform.IsConnected())
+
+        processes = platform.GetAllProcesses(error)
+        self.assertSuccess(error)
+        self.assertEqual(processes.GetSize(), 2)
+        self.assertEqual(len(processes), 2)
+
+        process_info = lldb.SBProcessInfo()
+        processes.GetProcessInfoAtIndex(0, process_info)
+        self.assertEqual(process_info.GetProcessID(), 95117)
+        self.assertEqual(process_info.GetName(), "foo")
+
+        processes.GetProcessInfoAtIndex(1, process_info)
+        self.assertEqual(process_info.GetProcessID(), 95126)
+        self.assertEqual(process_info.GetName(), "foo")
+
+        platform.DisconnectRemote()

Copy link
Member

@medismailben medismailben left a comment

Choose a reason for hiding this comment

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

LGTM with some comments

Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

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

LGTM

Add the ability to list all processes through the SB API.

rdar://116188959
@JDevlieghere JDevlieghere force-pushed the jdevlieghere/SBPlatformGetAllProcesses branch from 8611beb to 450be6e Compare October 6, 2023 04:36
@JDevlieghere JDevlieghere merged commit 8f378ff into llvm:main Oct 6, 2023
@JDevlieghere JDevlieghere deleted the jdevlieghere/SBPlatformGetAllProcesses branch October 6, 2023 17:43
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Oct 9, 2023
Add the ability to list all processes through the SB API.

rdar://116188959
(cherry picked from commit 8f378ff)
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