aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ScriptInterpreter/Python
diff options
context:
space:
mode:
authorjimingham <jingham@apple.com>2025-10-09 08:37:21 -0700
committerGitHub <noreply@github.com>2025-10-09 08:37:21 -0700
commit36bce68b97316363085ae3681e8dde33a62fc9b1 (patch)
treea7d732cc45aae98d91fc8747efd27c655ea5c423 /lldb/source/Plugins/ScriptInterpreter/Python
parentc4f36758b73fbf651650d8b650347e0ac172795f (diff)
downloadllvm-36bce68b97316363085ae3681e8dde33a62fc9b1.zip
llvm-36bce68b97316363085ae3681e8dde33a62fc9b1.tar.gz
llvm-36bce68b97316363085ae3681e8dde33a62fc9b1.tar.bz2
Add a scripted way to re-present a stop location (#158128)
This patch adds the notion of "Facade" locations which can be reported from a ScriptedResolver instead of the actual underlying breakpoint location for the breakpoint. Also add a "was_hit" method to the scripted resolver that allows the breakpoint to say which of these "Facade" locations was hit, and "get_location_description" to provide a description for the facade locations. I apologize in advance for the size of the patch. Almost all of what's here was necessary to (a) make the feature testable and (b) not break any of the current behavior. The motivation for this feature is given in the "Providing Facade Locations" section that I added to the python-reference.rst so I won't repeat it here. rdar://152112327
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python')
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp26
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp49
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h27
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h3
5 files changed, 111 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
index 660edaa..c9bb38d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
@@ -81,6 +81,32 @@ std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
return obj->GetAsString()->GetValue().str();
}
+lldb::BreakpointLocationSP ScriptedBreakpointPythonInterface::WasHit(
+ lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+ Status py_error;
+ lldb::BreakpointLocationSP loc_sp = Dispatch<lldb::BreakpointLocationSP>(
+ "was_hit", py_error, frame_sp, bp_loc_sp);
+
+ if (py_error.Fail())
+ return bp_loc_sp;
+
+ return loc_sp;
+}
+
+std::optional<std::string>
+ScriptedBreakpointPythonInterface::GetLocationDescription(
+ lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {
+ Status error;
+ StructuredData::ObjectSP obj =
+ Dispatch("get_location_description", error, bp_loc_sp, level);
+
+ 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 ...]"};
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
index 27bdd871..72da0a1 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
@@ -36,6 +36,12 @@ public:
bool ResolverCallback(SymbolContext sym_ctx) override;
lldb::SearchDepth GetDepth() override;
std::optional<std::string> GetShortHelp() override;
+ lldb::BreakpointLocationSP
+ WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp) override;
+ virtual std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) override;
static void Initialize();
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index 8083cca..4fdf2b1 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -81,6 +81,19 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
}
template <>
+lldb::StackFrameSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>(
+ python::PythonObject &p, Status &error) {
+ if (lldb::SBFrame *sb_frame = reinterpret_cast<lldb::SBFrame *>(
+ python::LLDBSWIGPython_CastPyObjectToSBFrame(p.get())))
+ return m_interpreter.GetOpaqueTypeFromSBFrame(*sb_frame);
+ error = Status::FromErrorString(
+ "Couldn't cast lldb::SBFrame to lldb_private::StackFrame.");
+
+ return nullptr;
+}
+
+template <>
SymbolContext
ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
python::PythonObject &p, Status &error) {
@@ -127,6 +140,24 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
}
template <>
+lldb::BreakpointLocationSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error) {
+ lldb::SBBreakpointLocation *sb_break_loc =
+ reinterpret_cast<lldb::SBBreakpointLocation *>(
+ python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(p.get()));
+
+ if (!sb_break_loc) {
+ error = Status::FromErrorStringWithFormat(
+ "Couldn't cast lldb::SBBreakpointLocation to "
+ "lldb::BreakpointLocationSP.");
+ return nullptr;
+ }
+
+ return m_interpreter.GetOpaqueTypeFromSBBreakpointLocation(*sb_break_loc);
+}
+
+template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error) {
lldb::SBAttachInfo *sb_attach_info = reinterpret_cast<lldb::SBAttachInfo *>(
@@ -194,4 +225,22 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx);
}
+template <>
+lldb::DescriptionLevel
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DescriptionLevel>(
+ python::PythonObject &p, Status &error) {
+ lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief;
+ llvm::Expected<unsigned long long> unsigned_or_err = p.AsUnsignedLongLong();
+ if (!unsigned_or_err) {
+ error = (Status::FromError(unsigned_or_err.takeError()));
+ return ret_val;
+ }
+ unsigned long long unsigned_val = *unsigned_or_err;
+ if (unsigned_val >= lldb::DescriptionLevel::kNumDescriptionLevels) {
+ error = Status("value too large for lldb::DescriptionLevel.");
+ return ret_val;
+ }
+ return static_cast<lldb::DescriptionLevel>(unsigned_val);
+}
+
#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index f769d3d..2335b2e 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -436,6 +436,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(lldb::BreakpointLocationSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::ProcessSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -464,10 +468,18 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg.get());
}
+ python::PythonObject Transform(lldb::StackFrameSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::DataExtractorSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(lldb::DescriptionLevel arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
template <typename T, typename U>
void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
// If U is not a PythonObject, don't touch it!
@@ -574,11 +586,21 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
python::PythonObject &p, Status &error);
template <>
+lldb::StackFrameSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>(
+ python::PythonObject &p, Status &error);
+
+template <>
lldb::BreakpointSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
python::PythonObject &p, Status &error);
template <>
+lldb::BreakpointLocationSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error);
+
+template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error);
@@ -601,6 +623,11 @@ lldb::ExecutionContextRefSP
ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error);
+template <>
+lldb::DescriptionLevel
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DescriptionLevel>(
+ python::PythonObject &p, Status &error);
+
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 4137786..7b39d29 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -107,6 +107,7 @@ public:
static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
+ static PythonObject ToSWIGWrapper(lldb::DescriptionLevel level);
static PythonObject
ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
@@ -256,11 +257,13 @@ public:
void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);