[lldb] Add support for ScriptedFrame to provide values/variables.#178575
[lldb] Add support for ScriptedFrame to provide values/variables.#178575bzcheeseman merged 1 commit intomainfrom
Conversation
8ccd0cf to
e481f65
Compare
a11fcee to
be1b9d1
Compare
This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.
There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.
This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.
stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
|
@llvm/pr-subscribers-lldb Author: Aman LaChapelle (bzcheeseman) ChangesStacked PRs:
[lldb] Add support for ScriptedFrame to provide values/variables.This patch adds plumbing to support the implementations of StackFrame::Get{}Variable{} on ScriptedFrame. The major pieces required are:
There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time. This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly. Full diff: https://github.com/llvm/llvm-project/pull/178575.diff 8 Files Affected:
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
index 8ef4b37d6ba12..90170d3bead5f 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
@@ -10,6 +10,7 @@
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
#include "ScriptedInterface.h"
+#include "lldb/API/SBValueList.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/lldb-private.h"
@@ -49,6 +50,16 @@ class ScriptedFrameInterface : virtual public ScriptedInterface {
virtual std::optional<std::string> GetRegisterContext() {
return std::nullopt;
}
+
+ virtual std::optional<lldb::ValueObjectListSP> GetVariables() {
+ return std::nullopt;
+ }
+
+ virtual lldb::ValueObjectSP
+ GetValueObjectForVariableExpression(llvm::StringRef expr, uint32_t options,
+ Status &error) {
+ return nullptr;
+ }
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
index 70ce101c6c834..caf37dc71e03e 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
@@ -9,6 +9,7 @@
#include "ScriptedFrame.h"
#include "Plugins/Process/Utility/RegisterContextMemory.h"
+#include "lldb/API/SBDeclaration.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -20,6 +21,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -28,6 +30,8 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/ValueObject/ValueObject.h"
+#include "lldb/ValueObject/ValueObjectList.h"
using namespace lldb;
using namespace lldb_private;
@@ -106,6 +110,30 @@ ScriptedFrame::Create(ThreadSP thread_sp,
if (maybe_sym_ctx)
sc = *maybe_sym_ctx;
+ // If we have any variables from the scripted interface, pull them out and add
+ // them to the ScriptedFrame object.
+ std::optional<ValueObjectListSP> maybe_variables =
+ scripted_frame_interface->GetVariables();
+ lldb::VariableListSP variable_list_sp = nullptr;
+ if (maybe_variables && *maybe_variables) {
+ variable_list_sp = std::make_shared<VariableList>();
+ ValueObjectListSP value_list_sp = *maybe_variables;
+
+ for (uint32_t i = 0, e = value_list_sp->GetSize(); i < e; ++i) {
+ ValueObjectSP v = value_list_sp->GetValueObjectAtIndex(i);
+ if (!v)
+ continue;
+
+ VariableSP var = v->GetVariable();
+ // TODO: We could in theory ask the scripted frame to *produce* a
+ // variable for this value object.
+ if (!var)
+ continue;
+
+ variable_list_sp->AddVariable(var);
+ }
+ }
+
lldb::RegisterContextSP reg_ctx_sp;
auto regs_or_err =
CreateRegisterContext(*scripted_frame_interface, *thread_sp, frame_id);
@@ -114,9 +142,10 @@ ScriptedFrame::Create(ThreadSP thread_sp,
else
reg_ctx_sp = *regs_or_err;
- return std::make_shared<ScriptedFrame>(thread_sp, scripted_frame_interface,
- frame_id, pc, sc, reg_ctx_sp,
- owned_script_object_sp);
+ return std::make_shared<ScriptedFrame>(
+ thread_sp, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp,
+ owned_script_object_sp, variable_list_sp,
+ maybe_variables.value_or(nullptr));
}
ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
@@ -124,13 +153,16 @@ ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
lldb::user_id_t id, lldb::addr_t pc,
SymbolContext &sym_ctx,
lldb::RegisterContextSP reg_ctx_sp,
- StructuredData::GenericSP script_object_sp)
+ StructuredData::GenericSP script_object_sp,
+ lldb::VariableListSP variables_sp,
+ lldb::ValueObjectListSP values_sp)
: StackFrame(thread_sp, /*frame_idx=*/id,
/*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp,
/*cfa=*/0, /*pc=*/pc,
/*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx),
m_scripted_frame_interface_sp(interface_sp),
- m_script_object_sp(script_object_sp) {
+ m_script_object_sp(script_object_sp), m_variable_list_sp(variables_sp),
+ m_value_objects_sp(values_sp) {
// FIXME: This should be part of the base class constructor.
m_stack_frame_kind = StackFrame::Kind::Synthetic;
}
@@ -265,3 +297,38 @@ lldb::RegisterContextSP ScriptedFrame::GetRegisterContext() {
return m_reg_context_sp;
}
+
+VariableList *ScriptedFrame::GetVariableList(bool get_file_globals,
+ Status *error_ptr) {
+ return m_variable_list_sp.get();
+}
+
+lldb::VariableListSP
+ScriptedFrame::GetInScopeVariableList(bool get_file_globals,
+ bool must_have_valid_location) {
+ return m_variable_list_sp;
+}
+
+lldb::ValueObjectSP ScriptedFrame::GetValueObjectForFrameVariable(
+ const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic) {
+ for (size_t i = 0, e = m_variable_list_sp->GetSize(); i < e; ++i) {
+ if (m_variable_list_sp->GetVariableAtIndex(i) == variable_sp) {
+ return m_value_objects_sp->GetValueObjectAtIndex(i);
+ }
+ }
+ return nullptr;
+}
+
+lldb::ValueObjectSP ScriptedFrame::GetValueForVariableExpressionPath(
+ llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+ uint32_t options, lldb::VariableSP &var_sp, Status &error) {
+ // Unless the frame implementation knows how to create variables (which it
+ // doesn't), we can't construct anything for the variable. This may seem
+ // somewhat out of place, but it's basically because of how this API is used -
+ // the print command uses this API to fill in var_sp; and this implementation
+ // can't do that!
+ (void)var_sp;
+ // Otherwise, delegate to the scripted frame interface pointer.
+ return m_scripted_frame_interface_sp->GetValueObjectForVariableExpression(
+ var_expr, options, error);
+}
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
index 0545548e912e6..5aef8f58b1aae 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
@@ -26,7 +26,9 @@ class ScriptedFrame : public lldb_private::StackFrame {
lldb::ScriptedFrameInterfaceSP interface_sp,
lldb::user_id_t frame_idx, lldb::addr_t pc,
SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp,
- StructuredData::GenericSP script_object_sp = nullptr);
+ StructuredData::GenericSP script_object_sp = nullptr,
+ lldb::VariableListSP variables_sp = nullptr,
+ lldb::ValueObjectListSP values_sp = nullptr);
~ScriptedFrame() override;
@@ -63,6 +65,21 @@ class ScriptedFrame : public lldb_private::StackFrame {
lldb::RegisterContextSP GetRegisterContext() override;
+ VariableList *GetVariableList(bool get_file_globals,
+ lldb_private::Status *error_ptr) override;
+
+ lldb::VariableListSP
+ GetInScopeVariableList(bool get_file_globals,
+ bool must_have_valid_location = false) override;
+
+ lldb::ValueObjectSP
+ GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
+ lldb::DynamicValueType use_dynamic) override;
+
+ lldb::ValueObjectSP GetValueForVariableExpressionPath(
+ llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+ uint32_t options, lldb::VariableSP &var_sp, Status &error) override;
+
bool isA(const void *ClassID) const override {
return ClassID == &ID || StackFrame::isA(ClassID);
}
@@ -82,6 +99,8 @@ class ScriptedFrame : public lldb_private::StackFrame {
lldb::ScriptedFrameInterfaceSP m_scripted_frame_interface_sp;
lldb_private::StructuredData::GenericSP m_script_object_sp;
+ lldb::VariableListSP m_variable_list_sp;
+ lldb::ValueObjectListSP m_value_objects_sp;
static char ID;
};
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
index 20ca7a2c01356..3782d9729bbf9 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
@@ -154,4 +154,31 @@ std::optional<std::string> ScriptedFramePythonInterface::GetRegisterContext() {
return obj->GetAsString()->GetValue().str();
}
+std::optional<lldb::ValueObjectListSP>
+ScriptedFramePythonInterface::GetVariables() {
+ Status error;
+ auto vals = Dispatch<lldb::ValueObjectListSP>("get_variables", error);
+
+ if (error.Fail()) {
+ return ErrorWithMessage<lldb::ValueObjectListSP>(LLVM_PRETTY_FUNCTION,
+ error.AsCString(), error);
+ }
+
+ return vals;
+}
+
+lldb::ValueObjectSP ScriptedFramePythonInterface::GetValueObjectForVariableExpression(
+ llvm::StringRef expr, uint32_t options, Status &status) {
+ Status dispatch_error;
+ auto val = Dispatch<lldb::ValueObjectSP>(
+ "get_value_for_variable_expression", dispatch_error, expr.data(), options, status);
+
+ if (dispatch_error.Fail()) {
+ return ErrorWithMessage<lldb::ValueObjectSP>(
+ LLVM_PRETTY_FUNCTION, dispatch_error.AsCString(), dispatch_error);
+ }
+
+ return val;
+}
+
#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
index 3aff237ae65d5..bb866c9146640 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
@@ -52,6 +52,12 @@ class ScriptedFramePythonInterface : public ScriptedFrameInterface,
StructuredData::DictionarySP GetRegisterInfo() override;
std::optional<std::string> GetRegisterContext() override;
+
+ std::optional<lldb::ValueObjectListSP> GetVariables() override;
+
+ lldb::ValueObjectSP
+ GetValueObjectForVariableExpression(llvm::StringRef expr, uint32_t options,
+ Status &status) override;
};
} // namespace lldb_private
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py b/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
index 964d213b16887..7dd74013b90f8 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
+++ b/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
@@ -730,3 +730,56 @@ def test_chained_frame_providers(self):
frame3 = thread.GetFrameAtIndex(3)
self.assertIsNotNone(frame3)
self.assertIn("thread_func", frame3.GetFunctionName())
+
+ def test_get_values(self):
+ """Test a frame that provides values."""
+ self.build()
+ # Set the breakpoint after the variable_in_main variable exists and can be queried.
+ target, process, thread, bkpt = lldbutil.run_to_line_breakpoint(
+ self, lldb.SBFileSpec(self.source), 35, only_one_thread=False
+ )
+
+ # Get original frame count.
+ original_frame_count = thread.GetNumFrames()
+ self.assertGreaterEqual(
+ original_frame_count, 2, "Should have at least 2 real frames"
+ )
+
+ # Import the test frame providers.
+ script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
+ self.runCmd("command script import " + script_path)
+
+ # Register a provider that can provide variables.
+ error = lldb.SBError()
+ target.RegisterScriptedFrameProvider(
+ "test_frame_providers.ValueProvidingFrameProvider",
+ lldb.SBStructuredData(),
+ error,
+ )
+ self.assertTrue(error.Success(), f"Failed to register provider: {error}")
+
+ # Verify we have 1 more frame.
+ new_frame_count = thread.GetNumFrames()
+ self.assertEqual(
+ new_frame_count,
+ original_frame_count + 1,
+ "Should have original frames + 1 extra frames",
+ )
+
+ # Check that we can get variables from this frame.
+ frame0 = thread.GetFrameAtIndex(0)
+ self.assertIsNotNone(frame0)
+ # Get every variable visible at this point
+ variables = frame0.GetVariables(True, True, True, False)
+ self.assertTrue(variables.IsValid() and variables.GetSize() == 1)
+
+ # Check that we can get values from paths. `_handler_one` is a special
+ # value we provide through only our expression handler in the frame
+ # implementation.
+ one = frame0.GetValueForVariablePath("_handler_one")
+ self.assertEqual(one.unsigned, 1)
+ var = frame0.GetValueForVariablePath("variable_in_main")
+ # The names won't necessarily match, but the values should (the frame renames the SBValue)
+ self.assertEqual(var.unsigned, variables.GetValueAtIndex(0).unsigned)
+ varp1 = frame0.GetValueForVariablePath("variable_in_main + 1")
+ self.assertEqual(varp1.unsigned, 124)
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp b/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
index 0298e88e4de16..e1d346c29052b 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
+++ b/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
@@ -29,6 +29,10 @@ void thread_func(int thread_num) {
int main(int argc, char **argv) {
std::thread threads[NUM_THREADS];
+ // Used as an existing C++ variable we can anchor on.
+ int variable_in_main = 123;
+ (void)variable_in_main;
+
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = std::thread(thread_func, i);
}
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py b/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
index 6233041f68a51..3a30e4fa96d6e 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
+++ b/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
@@ -458,3 +458,85 @@ def get_frame_at_index(self, index):
# Pass through input frames (shifted by 1)
return index - 1
return None
+
+
+class ValueProvidingFrame(ScriptedFrame):
+ """Scripted frame with a valid PC but no associated module."""
+
+ def __init__(self, thread, idx, pc, function_name, variable):
+ args = lldb.SBStructuredData()
+ super().__init__(thread, args)
+
+ self.idx = idx
+ self.pc = pc
+ self.function_name = function_name
+ self.variable = variable
+
+ def get_id(self):
+ """Return the frame index."""
+ return self.idx
+
+ def get_pc(self):
+ """Return the program counter."""
+ return self.pc
+
+ def get_function_name(self):
+ """Return the function name."""
+ return self.function_name
+
+ def is_artificial(self):
+ """Not artificial."""
+ return False
+
+ def is_hidden(self):
+ """Not hidden."""
+ return False
+
+ def get_register_context(self):
+ """No register context."""
+ return None
+
+ def get_variables(self):
+ """"""
+ out = lldb.SBValueList()
+ out.Append(self.variable)
+ return out
+
+ def get_value_for_variable_expression(self, expr, options, error: lldb.SBError):
+ out = lldb.SBValue()
+ if expr == "_handler_one":
+ out = self.variable.CreateValueFromExpression("_handler_one", "(uint32_t)1")
+ elif self.variable.name in expr:
+ out = self.variable.CreateValueFromExpression("_expr", expr)
+
+ if out.IsValid():
+ return out
+
+ error.SetErrorString(f"expression {expr} failed")
+ return None
+
+
+class ValueProvidingFrameProvider(ScriptedFrameProvider):
+ """Add a single 'value-provider' frame at the beginning."""
+
+ def __init__(self, input_frames, args):
+ super().__init__(input_frames, args)
+
+ @staticmethod
+ def get_description():
+ """Return a description of this provider."""
+ return "Add 'value-provider' frame at beginning"
+
+ def get_frame_at_index(self, index):
+ if index == 0:
+ f = self.input_frames.GetFrameAtIndex(index)
+ # Find some variable we can give to the frame.
+ variable = f.FindVariable("variable_in_main")
+ # Return synthetic "value-provider" frame
+ return ValueProvidingFrame(
+ self.thread, 0, 0xF00, "value-provider", variable
+ )
+ elif index - 1 < len(self.input_frames):
+ # Pass through input frames (shifted by 1)
+ return index - 1
+ return None
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
e481f65 to
eb2215a
Compare
This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.
There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.
This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.
stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
eb2215a to
cd2c467
Compare
cd2c467 to
c3d0c37
Compare
b46ed29 to
41eeb01
Compare
|
Also, would you mind including rdar://165708771 at the end of the commit message, thanks. |
41eeb01 to
88c0bf8
Compare
LOL still closing radars even after leaving Apple :P |
Looks like you can't avoid it :p |
medismailben
left a comment
There was a problem hiding this comment.
LGTM with comment addressed :)
This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.
There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.
This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.
Related radar: rdar://165708771
stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
88c0bf8 to
5d52734
Compare
…vm#178575) This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are: - A modification to ScriptedFrameInterface, so that we can actually call the python methods. - A corresponding update to the python implementation to call the python methods. - An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request. There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time. This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly. Related radar: rdar://165708771
|
/cherry-pick 10f2611 |
|
Failed to cherry-pick: 10f2611 https://github.com/llvm/llvm-project/actions/runs/21639721323 Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request |
…vm#178575) This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are: - A modification to ScriptedFrameInterface, so that we can actually call the python methods. - A corresponding update to the python implementation to call the python methods. - An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request. There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time. This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly. Related radar: rdar://165708771 (cherry picked from commit 10f2611)
…vm#178575) This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are: - A modification to ScriptedFrameInterface, so that we can actually call the python methods. - A corresponding update to the python implementation to call the python methods. - An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request. There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time. This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly. Related radar: rdar://165708771
…vm#178575) This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are: - A modification to ScriptedFrameInterface, so that we can actually call the python methods. - A corresponding update to the python implementation to call the python methods. - An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request. There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time. This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly. Related radar: rdar://165708771 (cherry picked from commit 10f2611)
Stacked PRs:
printdelegate to synthetic frames. #178602[lldb] Add support for ScriptedFrame to provide values/variables.
This patch adds plumbing to support the implementations of StackFrame::Get{}Variable{} on ScriptedFrame. The major pieces required are:
There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.
This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.
Related radar: rdar://165708771