Author: Jonas Devlieghere Date: 2023-10-06T10:43:31-07:00 New Revision: 8f378ff7a0a36137619a446b0bb13b8bc0ef6721
URL: https://github.com/llvm/llvm-project/commit/8f378ff7a0a36137619a446b0bb13b8bc0ef6721 DIFF: https://github.com/llvm/llvm-project/commit/8f378ff7a0a36137619a446b0bb13b8bc0ef6721.diff LOG: [lldb] Expose SBPlatform::GetAllProcesses to the SB API (#68378) Add the ability to list all processes through the SB API. rdar://116188959 Added: lldb/bindings/interface/SBProcessInfoListExtensions.i lldb/include/lldb/API/SBProcessInfoList.h lldb/source/API/SBProcessInfoList.cpp lldb/test/API/functionalities/gdb_remote_client/TestPlatformListProcesses.py Modified: lldb/bindings/headers.swig lldb/bindings/interfaces.swig lldb/include/lldb/API/LLDB.h lldb/include/lldb/API/SBDefines.h lldb/include/lldb/API/SBPlatform.h lldb/include/lldb/API/SBProcessInfo.h lldb/include/lldb/Target/Platform.h lldb/include/lldb/Utility/ProcessInfo.h lldb/source/API/CMakeLists.txt lldb/source/API/SBPlatform.cpp lldb/source/Target/Platform.cpp Removed: ################################################################################ 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..9d3f65c46fbbe69 --- /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 a574a461d4920ae..895c6221a8073cf 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..a711bcb58301e61 --- /dev/null +++ b/lldb/source/API/SBProcessInfoList.cpp @@ -0,0 +1,74 @@ +//===-- 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 "lldb/API/SBProcessInfo.h" +#include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/ProcessInfo.h" + +#include "Utils.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() _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits