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

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

rdar://116188959
This commit is contained in:
Jonas Devlieghere
2023-10-06 10:43:31 -07:00
committed by GitHub
parent 70368eaeb8
commit 8f378ff7a0
15 changed files with 244 additions and 1 deletions

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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;

View File

@@ -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 @@ public:
SBProcess Attach(SBAttachInfo &attach_info, const SBDebugger &debugger,
SBTarget &target, SBError &error);
SBProcessInfoList GetAllProcesses(SBError &error);
SBError Kill(const lldb::pid_t pid);
SBError

View File

@@ -55,6 +55,7 @@ public:
private:
friend class SBProcess;
friend class SBProcessInfoList;
lldb_private::ProcessInstanceInfo &ref();

View File

@@ -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

View File

@@ -407,6 +407,8 @@ public:
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 @@ public:
}
virtual CompilerType GetSiginfoType(const llvm::Triple &triple);
virtual Args GetExtraStartupCommands();
typedef std::function<Status(const ModuleSpec &module_spec,

View File

@@ -187,6 +187,26 @@ protected:
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.

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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()