[Lldb-commits] [lldb] [lldb] Expose SBPlatform::GetAllProcesses to the SB API (PR #68378)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 5 21:08:34 PDT 2023
https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/68378
Add the ability to list all processes through the SB API.
rdar://116188959
>From 8611bebd2b6cd4f6de797240c1cb184af71f384d Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 5 Oct 2023 21:07:03 -0700
Subject: [PATCH] [lldb] Expose SBPlatform::GetAllProcesses to the SB API
Add the ability to list all processes through the SB API.
rdar://116188959
---
lldb/bindings/headers.swig | 1 +
.../interface/SBProcessInfoListExtensions.i | 13 ++++
lldb/bindings/interfaces.swig | 2 +
lldb/include/lldb/API/LLDB.h | 1 +
lldb/include/lldb/API/SBDefines.h | 1 +
lldb/include/lldb/API/SBPlatform.h | 4 +
lldb/include/lldb/API/SBProcessInfo.h | 1 +
lldb/include/lldb/API/SBProcessInfoList.h | 46 ++++++++++++
lldb/include/lldb/Target/Platform.h | 4 +-
lldb/include/lldb/Utility/ProcessInfo.h | 20 +++++
lldb/source/API/CMakeLists.txt | 1 +
lldb/source/API/SBPlatform.cpp | 15 ++++
lldb/source/API/SBProcessInfoList.cpp | 73 +++++++++++++++++++
lldb/source/Target/Platform.cpp | 8 ++
.../TestPlatformListProcesses.py | 54 ++++++++++++++
15 files changed, 243 insertions(+), 1 deletion(-)
create mode 100644 lldb/bindings/interface/SBProcessInfoListExtensions.i
create mode 100644 lldb/include/lldb/API/SBProcessInfoList.h
create mode 100644 lldb/source/API/SBProcessInfoList.cpp
create mode 100644 lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py
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()
More information about the lldb-commits
mailing list