From 36bce68b97316363085ae3681e8dde33a62fc9b1 Mon Sep 17 00:00:00 2001 From: jimingham Date: Thu, 9 Oct 2025 08:37:21 -0700 Subject: 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 --- .../Python/Interfaces/ScriptedPythonInterface.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp') diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index 8083ccae0402..4fdf2b12a550 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -80,6 +80,19 @@ ScriptedPythonInterface::ExtractValueFromPythonObject( return nullptr; } +template <> +lldb::StackFrameSP +ScriptedPythonInterface::ExtractValueFromPythonObject( + python::PythonObject &p, Status &error) { + if (lldb::SBFrame *sb_frame = reinterpret_cast( + 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( @@ -126,6 +139,24 @@ ScriptedPythonInterface::ExtractValueFromPythonObject( return m_interpreter.GetOpaqueTypeFromSBBreakpoint(*sb_breakpoint); } +template <> +lldb::BreakpointLocationSP +ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error) { + lldb::SBBreakpointLocation *sb_break_loc = + reinterpret_cast( + 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) { @@ -194,4 +225,22 @@ ScriptedPythonInterface::ExtractValueFromPythonObject< return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx); } +template <> +lldb::DescriptionLevel +ScriptedPythonInterface::ExtractValueFromPythonObject( + python::PythonObject &p, Status &error) { + lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief; + llvm::Expected 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(unsigned_val); +} + #endif -- cgit v1.2.3