Switch the ScriptedBreakpointResolver over to the ScriptedInterface form (#150720)

This is NFC, I'm modernizing the interface before I add to it in a
subsequent commit.
This commit is contained in:
jimingham
2025-07-28 15:11:22 -07:00
committed by GitHub
parent 6bcff9eb13
commit 4c8e79f815
22 changed files with 328 additions and 217 deletions

View File

@@ -229,78 +229,6 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject
return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict);
}
PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_impl,
const lldb::BreakpointSP &breakpoint_sp) {
if (python_class_name == NULL || python_class_name[0] == '\0' ||
!session_dictionary_name)
return PythonObject();
PyErr_Cleaner py_err_cleaner(true);
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
session_dictionary_name);
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
python_class_name, dict);
if (!pfunc.IsAllocated())
return PythonObject();
PythonObject result =
pfunc(SWIGBridge::ToSWIGWrapper(breakpoint_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict);
// FIXME: At this point we should check that the class we found supports all
// the methods that we need.
if (result.IsAllocated()) {
// Check that __callback__ is defined:
auto callback_func = result.ResolveName<PythonCallable>("__callback__");
if (callback_func.IsAllocated())
return result;
}
return PythonObject();
}
unsigned int lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx) {
PyErr_Cleaner py_err_cleaner(false);
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
auto pfunc = self.ResolveName<PythonCallable>(method_name);
if (!pfunc.IsAllocated())
return 0;
PythonObject result = sym_ctx ? pfunc(SWIGBridge::ToSWIGWrapper(*sym_ctx)) : pfunc();
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
return 0;
}
// The callback will return a bool, but we're need to also return ints
// so we're squirrelling the bool through as an int... And if you return
// nothing, we'll continue.
if (strcmp(method_name, "__callback__") == 0) {
if (result.get() == Py_False)
return 0;
else
return 1;
}
long long ret_val = unwrapOrSetPythonException(As<long long>(result));
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
return 0;
}
return ret_val;
}
// wrapper that calls an optional instance member of an object taking no
// arguments
static PyObject *LLDBSwigPython_CallOptionalMember(
@@ -554,6 +482,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * dat
return sb_ptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject * data) {
lldb::SBSymbolContext *sb_ptr = nullptr;
int valid_cast =
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBSymbolContext, 0);
if (valid_cast == -1)
return NULL;
return sb_ptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
lldb::SBValue *sb_ptr = NULL;

View File

@@ -80,6 +80,8 @@ protected:
lldb_private::SymbolContext *get() const;
friend class lldb_private::ScriptInterpreter;
private:
std::unique_ptr<lldb_private::SymbolContext> m_opaque_up;
};

View File

@@ -12,6 +12,7 @@
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
#include "lldb/lldb-forward.h"
namespace lldb_private {
@@ -64,7 +65,8 @@ private:
std::string m_class_name;
lldb::SearchDepth m_depth;
StructuredDataImpl m_args;
StructuredData::GenericSP m_implementation_sp;
Status m_error;
lldb::ScriptedBreakpointInterfaceSP m_interface_sp;
BreakpointResolverScripted(const BreakpointResolverScripted &) = delete;
const BreakpointResolverScripted &

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// 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_INTERPRETER_INTERFACES_SCRIPTEDBREAKPOINTINTERFACE_H
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDBREAKPOINTINTERFACE_H
#include "ScriptedInterface.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
class ScriptedBreakpointInterface : public ScriptedInterface {
public:
virtual llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name, lldb::BreakpointSP break_sp,
const StructuredDataImpl &args_sp) = 0;
/// "ResolverCallback" will get called when a new module is loaded. The
/// new module information is passed in sym_ctx. The Resolver will add
/// any breakpoint locations it found in that module.
virtual bool ResolverCallback(SymbolContext sym_ctx) { return true; }
virtual lldb::SearchDepth GetDepth() { return lldb::eSearchDepthModule; }
virtual std::optional<std::string> GetShortHelp() { return nullptr; }
};
} // namespace lldb_private
#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H

View File

@@ -18,6 +18,7 @@
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/SearchFilter.h"
@@ -29,6 +30,7 @@
#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
#include "lldb/Interpreter/ScriptObject.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
@@ -257,26 +259,6 @@ public:
return false;
}
virtual StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) {
return StructuredData::GenericSP();
}
virtual bool
ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
SymbolContext *sym_ctx)
{
return false;
}
virtual lldb::SearchDepth
ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
{
return lldb::eSearchDepthModule;
}
virtual StructuredData::ObjectSP
LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
return StructuredData::ObjectSP();
@@ -566,6 +548,11 @@ public:
return {};
}
virtual lldb::ScriptedBreakpointInterfaceSP
CreateScriptedBreakpointInterface() {
return {};
}
virtual StructuredData::ObjectSP
CreateStructuredDataFromScriptObject(ScriptObject obj) {
return {};
@@ -580,6 +567,9 @@ public:
lldb::StreamSP GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
SymbolContext
GetOpaqueTypeFromSBSymbolContext(const lldb::SBSymbolContext &sym_ctx) const;
lldb::BreakpointSP
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;

View File

@@ -188,6 +188,7 @@ class Scalar;
class ScriptInterpreter;
class ScriptInterpreterLocker;
class ScriptedMetadata;
class ScriptedBreakpointInterface;
class ScriptedPlatformInterface;
class ScriptedProcessInterface;
class ScriptedStopHookInterface;
@@ -418,6 +419,8 @@ typedef std::shared_ptr<lldb_private::ScriptedThreadInterface>
ScriptedThreadInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
ScriptedThreadPlanInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedBreakpointInterface>
ScriptedBreakpointInterfaceSP;
typedef std::shared_ptr<lldb_private::Section> SectionSP;
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
typedef std::weak_ptr<lldb_private::Section> SectionWP;

View File

@@ -35,7 +35,7 @@ BreakpointResolverScripted::BreakpointResolverScripted(
void BreakpointResolverScripted::CreateImplementationIfNeeded(
BreakpointSP breakpoint_sp) {
if (m_implementation_sp)
if (m_interface_sp)
return;
if (m_class_name.empty())
@@ -50,8 +50,27 @@ void BreakpointResolverScripted::CreateImplementationIfNeeded(
if (!script_interp)
return;
m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
m_class_name.c_str(), m_args, breakpoint_sp);
m_interface_sp = script_interp->CreateScriptedBreakpointInterface();
if (!m_interface_sp) {
m_error = Status::FromErrorStringWithFormat(
"BreakpointResolverScripted::%s () - ERROR: %s", __FUNCTION__,
"Script interpreter couldn't create Scripted Breakpoint Interface");
return;
}
auto obj_or_err =
m_interface_sp->CreatePluginObject(m_class_name, breakpoint_sp, m_args);
if (!obj_or_err) {
m_error = Status::FromError(obj_or_err.takeError());
return;
}
StructuredData::ObjectSP object_sp = *obj_or_err;
if (!object_sp || !object_sp->IsValid()) {
m_error = Status::FromErrorStringWithFormat(
"ScriptedBreakpoint::%s () - ERROR: %s", __FUNCTION__,
"Failed to create valid script object");
}
}
void BreakpointResolverScripted::NotifyBreakpointSet() {
@@ -104,13 +123,10 @@ ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
SearchFilter &filter, SymbolContext &context, Address *addr) {
bool should_continue = true;
if (!m_implementation_sp)
if (!m_interface_sp)
return Searcher::eCallbackReturnStop;
ScriptInterpreter *interp = GetScriptInterpreter();
should_continue = interp->ScriptedBreakpointResolverSearchCallback(
m_implementation_sp,
&context);
should_continue = m_interface_sp->ResolverCallback(context);
if (should_continue)
return Searcher::eCallbackReturnContinue;
@@ -120,25 +136,21 @@ Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
lldb::SearchDepth
BreakpointResolverScripted::GetDepth() {
lldb::SearchDepth depth = lldb::eSearchDepthModule;
if (m_implementation_sp) {
ScriptInterpreter *interp = GetScriptInterpreter();
depth = interp->ScriptedBreakpointResolverSearchDepth(
m_implementation_sp);
}
if (m_interface_sp)
depth = m_interface_sp->GetDepth();
return depth;
}
void BreakpointResolverScripted::GetDescription(Stream *s) {
StructuredData::GenericSP generic_sp;
std::string short_help;
std::optional<std::string> short_help;
if (m_implementation_sp) {
ScriptInterpreter *interp = GetScriptInterpreter();
interp->GetShortHelpForCommandObject(m_implementation_sp,
short_help);
if (m_interface_sp) {
short_help = m_interface_sp->GetShortHelp();
}
if (!short_help.empty())
s->PutCString(short_help.c_str());
if (short_help && !short_help->empty())
s->PutCString(short_help->c_str());
else
s->Printf("python class = %s", m_class_name.c_str());
}

View File

@@ -116,6 +116,13 @@ lldb::StreamSP ScriptInterpreter::GetOpaqueTypeFromSBStream(
return nullptr;
}
SymbolContext ScriptInterpreter::GetOpaqueTypeFromSBSymbolContext(
const lldb::SBSymbolContext &sb_sym_ctx) const {
if (sb_sym_ctx.m_opaque_up)
return *sb_sym_ctx.m_opaque_up.get();
return {};
}
std::optional<MemoryRegionInfo>
ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
const lldb::SBMemoryRegionInfo &mem_region) const {

View File

@@ -26,6 +26,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces PLUGIN
ScriptedProcessPythonInterface.cpp
ScriptedPythonInterface.cpp
ScriptedStopHookPythonInterface.cpp
ScriptedBreakpointPythonInterface.cpp
ScriptedThreadPlanPythonInterface.cpp
ScriptedThreadPythonInterface.cpp

View File

@@ -29,6 +29,7 @@ void ScriptInterpreterPythonInterfaces::Initialize() {
ScriptedPlatformPythonInterface::Initialize();
ScriptedProcessPythonInterface::Initialize();
ScriptedStopHookPythonInterface::Initialize();
ScriptedBreakpointPythonInterface::Initialize();
ScriptedThreadPlanPythonInterface::Initialize();
}
@@ -37,6 +38,7 @@ void ScriptInterpreterPythonInterfaces::Terminate() {
ScriptedPlatformPythonInterface::Terminate();
ScriptedProcessPythonInterface::Terminate();
ScriptedStopHookPythonInterface::Terminate();
ScriptedBreakpointPythonInterface::Terminate();
ScriptedThreadPlanPythonInterface::Terminate();
}

View File

@@ -16,6 +16,7 @@
#if LLDB_ENABLE_PYTHON
#include "OperatingSystemPythonInterface.h"
#include "ScriptedBreakpointPythonInterface.h"
#include "ScriptedPlatformPythonInterface.h"
#include "ScriptedProcessPythonInterface.h"
#include "ScriptedStopHookPythonInterface.h"

View File

@@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// 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/Core/PluginManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
#if LLDB_ENABLE_PYTHON
// LLDB Python header must be included first
#include "../lldb-python.h"
#include "../SWIGPythonBridge.h"
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedBreakpointPythonInterface.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;
ScriptedBreakpointPythonInterface::ScriptedBreakpointPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedBreakpointInterface(), ScriptedPythonInterface(interpreter) {}
llvm::Expected<StructuredData::GenericSP>
ScriptedBreakpointPythonInterface::CreatePluginObject(
llvm::StringRef class_name, lldb::BreakpointSP break_sp,
const StructuredDataImpl &args_sp) {
return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
break_sp, args_sp);
}
bool ScriptedBreakpointPythonInterface::ResolverCallback(
SymbolContext sym_ctx) {
Status error;
StructuredData::ObjectSP obj = Dispatch("__callback__", error, sym_ctx);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
Log *log = GetLog(LLDBLog::Script);
LLDB_LOG(log, "Error calling __callback__ method: {1}", error);
return true;
}
return obj->GetBooleanValue();
}
lldb::SearchDepth ScriptedBreakpointPythonInterface::GetDepth() {
Status error;
StructuredData::ObjectSP obj = Dispatch("__get_depth__", error);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
return lldb::eSearchDepthModule;
}
uint64_t value = obj->GetUnsignedIntegerValue();
if (value <= lldb::kLastSearchDepthKind)
return (lldb::SearchDepth)value;
// This is what we were doing on error before, though I'm not sure that's
// better than returning eSearchDepthInvalid.
return lldb::eSearchDepthModule;
}
std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_short_help", error);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
return {};
}
return obj->GetAsString()->GetValue().str();
}
void ScriptedBreakpointPythonInterface::Initialize() {
const std::vector<llvm::StringRef> ci_usages = {
"breakpoint set -P classname [-k key -v value ...]"};
const std::vector<llvm::StringRef> api_usages = {
"SBTarget.BreakpointCreateFromScript"};
PluginManager::RegisterPlugin(
GetPluginNameStatic(),
llvm::StringRef("Create a breakpoint that chooses locations based on "
"user-created callbacks"),
CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
}
void ScriptedBreakpointPythonInterface::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
#endif

View File

@@ -0,0 +1,53 @@
//===-- ScriptedBreakpointPythonInterface.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_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H
#include "lldb/Host/Config.h"
#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
#if LLDB_ENABLE_PYTHON
#include "ScriptedPythonInterface.h"
namespace lldb_private {
class ScriptedBreakpointPythonInterface : public ScriptedBreakpointInterface,
public ScriptedPythonInterface,
public PluginInterface {
public:
ScriptedBreakpointPythonInterface(ScriptInterpreterPythonImpl &interpreter);
llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name, lldb::BreakpointSP break_sp,
const StructuredDataImpl &args_sp) override;
llvm::SmallVector<AbstractMethodRequirement>
GetAbstractMethodRequirements() const override {
return llvm::SmallVector<AbstractMethodRequirement>({{"__callback__", 2}});
}
bool ResolverCallback(SymbolContext sym_ctx) override;
lldb::SearchDepth GetDepth() override;
std::optional<std::string> GetShortHelp() override;
static void Initialize();
static void Terminate();
static llvm::StringRef GetPluginNameStatic() {
return "ScriptedBreakpointPythonInterface";
}
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
};
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H

View File

@@ -17,6 +17,7 @@
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPythonInterface.h"
#include "lldb/Symbol/SymbolContext.h"
#include <optional>
using namespace lldb;
@@ -79,6 +80,20 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
return nullptr;
}
template <>
SymbolContext
ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
python::PythonObject &p, Status &error) {
if (lldb::SBSymbolContext *sb_symbol_context =
reinterpret_cast<lldb::SBSymbolContext *>(
python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(p.get())))
return m_interpreter.GetOpaqueTypeFromSBSymbolContext(*sb_symbol_context);
error = Status::FromErrorString(
"Couldn't cast lldb::SBSymbolContext to lldb_private::SymbolContext.");
return {};
}
template <>
lldb::DataExtractorSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(

View File

@@ -432,6 +432,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::BreakpointSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::ProcessSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -452,6 +456,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(const SymbolContext &arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::StreamSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg.get());
}
@@ -555,6 +563,11 @@ template <>
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
python::PythonObject &p, Status &error);
template <>
SymbolContext
ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
python::PythonObject &p, Status &error);
template <>
lldb::StreamSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(

View File

@@ -151,15 +151,6 @@ public:
const char *session_dictionary_name,
lldb::DebuggerSP debugger_sp);
static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
static unsigned int
LLDBSwigPythonCallBreakpointResolver(void *implementor,
const char *method_name,
lldb_private::SymbolContext *sym_ctx);
static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
uint32_t max);
@@ -270,6 +261,7 @@ void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data);

View File

@@ -1550,6 +1550,11 @@ ScriptInterpreterPythonImpl::CreateScriptedStopHookInterface() {
return std::make_shared<ScriptedStopHookPythonInterface>(*this);
}
ScriptedBreakpointInterfaceSP
ScriptInterpreterPythonImpl::CreateScriptedBreakpointInterface() {
return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
}
ScriptedThreadInterfaceSP
ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
return std::make_shared<ScriptedThreadPythonInterface>(*this);
@@ -1576,75 +1581,6 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
return py_obj.CreateStructuredObject();
}
StructuredData::GenericSP
ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
const char *class_name, const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::GenericSP();
if (!bkpt_sp.get())
return StructuredData::GenericSP();
Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
ScriptInterpreterPythonImpl *python_interpreter =
GetPythonInterpreter(debugger);
if (!python_interpreter)
return StructuredData::GenericSP();
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
PythonObject ret_val =
SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
bkpt_sp);
return StructuredData::GenericSP(
new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback(
StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) {
bool should_continue = false;
if (implementor_sp) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
should_continue = SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
implementor_sp->GetValue(), "__callback__", sym_ctx);
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
}
}
return should_continue;
}
lldb::SearchDepth
ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
StructuredData::GenericSP implementor_sp) {
int depth_as_int = lldb::eSearchDepthModule;
if (implementor_sp) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
depth_as_int = SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
implementor_sp->GetValue(), "__get_depth__", nullptr);
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
}
}
if (depth_as_int == lldb::eSearchDepthInvalid)
return lldb::eSearchDepthModule;
if (depth_as_int <= lldb::kLastSearchDepthKind)
return (lldb::SearchDepth)depth_as_int;
return lldb::eSearchDepthModule;
}
StructuredData::ObjectSP
ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
lldb_private::Status &error) {

View File

@@ -80,17 +80,6 @@ public:
StructuredData::ObjectSP
CreateStructuredDataFromScriptObject(ScriptObject obj) override;
StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) override;
bool ScriptedBreakpointResolverSearchCallback(
StructuredData::GenericSP implementor_sp,
SymbolContext *sym_ctx) override;
lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
StructuredData::GenericSP implementor_sp) override;
StructuredData::GenericSP
CreateFrameRecognizer(const char *class_name) override;
@@ -105,6 +94,9 @@ public:
lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() override;
lldb::ScriptedBreakpointInterfaceSP
CreateScriptedBreakpointInterface() override;
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
lldb::ScriptedThreadPlanInterfaceSP

View File

@@ -36,6 +36,7 @@
#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h"
#include "lldb/Interpreter/OptionGroupWatchpoint.h"
#include "lldb/Interpreter/OptionValues.h"

View File

@@ -235,11 +235,13 @@ class TestScriptedResolver(TestBase):
substrs=["2"],
msg="Was only passed modules",
)
print(f"Made first breakpoint: {bkpt}")
bkpt = None
# Make a breakpoint that asks for modules, check that we didn't get any files:
bkpt = target.BreakpointCreateFromScript(
"resolver.ResolverModuleDepth", extra_args, module_list, file_list
)
print(f"Made Second breakpoint: {bkpt}")
self.assertGreater(
bkpt.GetNumLocations(), 0, "ResolverModuleDepth got no locations."
)

View File

@@ -13,6 +13,7 @@ class Resolver:
Resolver.got_files = 0
def __callback__(self, sym_ctx):
print("Resolver callback called")
sym_name = "not_a_real_function_name"
sym_item = self.extra_args.GetValueForKey("symbol")
if sym_item.IsValid():
@@ -34,9 +35,18 @@ class Resolver:
return
if sym_ctx.module.IsValid():
print(f"Looking for {sym_name}")
sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode)
if sym.IsValid():
print(f"Adding location at {sym.GetStartAddress()} to {self.bkpt}")
self.bkpt.AddLocation(sym.GetStartAddress())
print(f"After addition: {self.bkpt}")
else:
print("Didn't find it, however...")
print(f"GotFiles: {Resolver.got_files}")
for func in Resolver.func_list:
print(f"Function: func")
def get_short_help(self):
return "I am a python breakpoint resolver"
@@ -46,17 +56,31 @@ class ResolverModuleDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthModule
def __callback__(self, sym_ctx):
print(f"About to call the Resolver callback for {self.bkpt}")
Resolver.__callback__(self, sym_ctx)
print("Called the callback for ResolverModuleDepth")
class ResolverCUDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthCompUnit
def __callback__(self, sym_ctx):
Resolver.__callback__(self, sym_ctx)
class ResolverFuncDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthFunction
def __callback__(self, sym_ctx):
Resolver.__callback__(self, sym_ctx)
class ResolverBadDepth(Resolver):
def __get_depth__(self):
return lldb.kLastSearchDepthKind + 1
def __callback__(self, sym_ctx):
Resolver.__callback__(self, sym_ctx)

View File

@@ -80,20 +80,6 @@ lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject(
return python::PythonObject();
}
python::PythonObject lldb_private::python::SWIGBridge::
LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp) {
return python::PythonObject();
}
unsigned int
lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx) {
return 0;
}
size_t lldb_private::python::SWIGBridge::LLDBSwigPython_CalculateNumChildren(
PyObject *implementor, uint32_t max) {
return 0;
@@ -144,6 +130,11 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) {
return nullptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(
PyObject *data) {
return nullptr;
}
void *
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data) {
return nullptr;