https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/127566
>From 6f59b1116dd83b9cce526103cca98a5d2056720f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Mon, 17 Feb 2025 20:58:30 -0800 Subject: [PATCH 1/2] [lldb] Store the return ValueObject in the CommandReturnObject There are a lot of lldb commands whose result is really a ValueObject that we then print with the ValueObjectPrinter. Now that we have the ability to access the SBCommandReturnObject through a callback (#125006), we can store the resultant ValueObject in the return object, allowing an IDE to access the SBValue and do its own rich formatting. rdar://143965453 --- lldb/include/lldb/API/SBCommandReturnObject.h | 2 ++ lldb/include/lldb/API/SBValue.h | 1 + lldb/include/lldb/Interpreter/CommandReturnObject.h | 9 +++++++++ lldb/source/API/SBCommandReturnObject.cpp | 10 ++++++++++ lldb/source/Commands/CommandObjectDWIMPrint.cpp | 3 +++ lldb/source/Commands/CommandObjectExpression.cpp | 2 ++ lldb/source/Commands/CommandObjectFrame.cpp | 1 + .../TestSBCommandReturnObject.py | 13 +++++++++++++ 8 files changed, 41 insertions(+) diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h index 9a63c1f96aa70..96dda239d3c97 100644 --- a/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -136,6 +136,8 @@ class LLDB_API SBCommandReturnObject { void SetError(const char *error_cstr); + lldb::SBValue GetReturnValue(lldb::DynamicValueType use_dynamic); + protected: friend class SBCommandInterpreter; friend class SBOptions; diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 46ef6daa95264..75d20a4378f09 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -442,6 +442,7 @@ class LLDB_API SBValue { protected: friend class SBBlock; + friend class SBCommandReturnObject; friend class SBFrame; friend class SBModule; friend class SBTarget; diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h index 803bcd76995ed..1a6cc5c6de060 100644 --- a/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -165,6 +165,12 @@ class CommandReturnObject { return m_diagnostic_indent; } + lldb::ValueObjectSP GetValueObjectSP() const { return m_value_object_sp; } + + void SetValueObjectSP(lldb::ValueObjectSP value_object_sp) { + m_value_object_sp = value_object_sp; + } + lldb::ReturnStatus GetStatus() const; void SetStatus(lldb::ReturnStatus status); @@ -197,6 +203,9 @@ class CommandReturnObject { lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; + /// An optional return ValueObjectSP. + lldb::ValueObjectSP m_value_object_sp; + bool m_did_change_process_state = false; bool m_suppress_immediate_output = false; diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp index 6f54581e64ef4..085bfac57c0a8 100644 --- a/lldb/source/API/SBCommandReturnObject.cpp +++ b/lldb/source/API/SBCommandReturnObject.cpp @@ -12,6 +12,7 @@ #include "lldb/API/SBFile.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStructuredData.h" +#include "lldb/API/SBValue.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/ConstString.h" @@ -356,3 +357,12 @@ void SBCommandReturnObject::SetError(const char *error_cstr) { if (error_cstr) ref().AppendError(error_cstr); } + +SBValue +SBCommandReturnObject::GetReturnValue(lldb::DynamicValueType use_dynamic) { + LLDB_INSTRUMENT_VA(this, use_dynamic); + + SBValue sb_value; + sb_value.SetSP(ref().GetValueObjectSP(), use_dynamic); + return sb_value; +} diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp index d4d038d28f675..aab99441c63a3 100644 --- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp +++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp @@ -205,6 +205,9 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command, ExpressionResults expr_result = target.EvaluateExpression( expr, exe_scope, valobj_sp, eval_options, &fixed_expression); + if (valobj_sp) + result.SetValueObjectSP(valobj_sp); + // Record the position of the expression in the command. std::optional<uint16_t> indent; if (fixed_expression.empty()) { diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 7e26381c92405..b0c92d9391b13 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -434,6 +434,8 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, } if (result_valobj_sp) { + result.SetValueObjectSP(result_valobj_sp); + Format format = m_format_options.GetFormat(); if (result_valobj_sp->GetError().Success()) { diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index a5709b36f52ee..96612fdbec6d5 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -152,6 +152,7 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed { return; } + result.SetValueObjectSP(valobj_sp); DumpValueObjectOptions::DeclPrintingHelper helper = [&valobj_sp](ConstString type, ConstString var, const DumpValueObjectOptions &opts, diff --git a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py index 2193b7270d0b4..0fee54eb5fe1d 100644 --- a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py +++ b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py @@ -33,3 +33,16 @@ def test_get_command(self): ci.HandleCommand("help help", res) self.assertTrue(res.Succeeded()) self.assertEqual(res.GetCommand(), "help help") + + value = res.GetReturnValue(lldb.eNoDynamicValues) + self.assertFalse(value) + + def test_get_value(self): + res = lldb.SBCommandReturnObject() + ci = self.dbg.GetCommandInterpreter() + ci.HandleCommand("p 1 + 1", res) + self.assertTrue(res.Succeeded()) + + value = res.GetReturnValue(lldb.eNoDynamicValues) + self.assertTrue(value) + self.assertEqual(value.GetValue(), "2") >From 83ea8516bdd5b127b5e5046fd35c213ab46b51c2 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 18 Feb 2025 11:20:08 -0800 Subject: [PATCH 2/2] Store SBValueList instead of SBValue --- lldb/include/lldb/API/SBCommandReturnObject.h | 2 +- .../lldb/Interpreter/CommandReturnObject.h | 17 ++++++++--------- .../lldb/ValueObject/ValueObjectList.h | 2 -- lldb/source/API/SBCommandReturnObject.cpp | 18 +++++++++++++----- .../Commands/CommandObjectDWIMPrint.cpp | 2 +- .../Commands/CommandObjectExpression.cpp | 2 +- lldb/source/Commands/CommandObjectFrame.cpp | 17 ++++++++++++----- lldb/source/Commands/CommandObjectTarget.cpp | 19 ++++++++++++------- lldb/source/ValueObject/ValueObjectList.cpp | 6 ------ .../TestSBCommandReturnObject.py | 10 +++++----- .../API/commands/frame/var/TestFrameVar.py | 9 ++++++++- .../target_var/TestTargetVar.py | 9 +++++++++ 12 files changed, 70 insertions(+), 43 deletions(-) diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h index 96dda239d3c97..6386bd250afa5 100644 --- a/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -136,7 +136,7 @@ class LLDB_API SBCommandReturnObject { void SetError(const char *error_cstr); - lldb::SBValue GetReturnValue(lldb::DynamicValueType use_dynamic); + lldb::SBValueList GetValues(lldb::DynamicValueType use_dynamic); protected: friend class SBCommandInterpreter; diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h index 1a6cc5c6de060..d53aeb81be2ba 100644 --- a/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -14,6 +14,7 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StreamTee.h" #include "lldb/Utility/StructuredData.h" +#include "lldb/ValueObject/ValueObjectList.h" #include "lldb/lldb-private.h" #include "llvm/ADT/StringRef.h" @@ -134,7 +135,7 @@ class CommandReturnObject { __attribute__((format(printf, 2, 3))); template <typename... Args> - void AppendMessageWithFormatv(const char *format, Args &&... args) { + void AppendMessageWithFormatv(const char *format, Args &&...args) { AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str()); } @@ -144,12 +145,12 @@ class CommandReturnObject { } template <typename... Args> - void AppendWarningWithFormatv(const char *format, Args &&... args) { + void AppendWarningWithFormatv(const char *format, Args &&...args) { AppendWarning(llvm::formatv(format, std::forward<Args>(args)...).str()); } template <typename... Args> - void AppendErrorWithFormatv(const char *format, Args &&... args) { + void AppendErrorWithFormatv(const char *format, Args &&...args) { AppendError(llvm::formatv(format, std::forward<Args>(args)...).str()); } @@ -165,11 +166,9 @@ class CommandReturnObject { return m_diagnostic_indent; } - lldb::ValueObjectSP GetValueObjectSP() const { return m_value_object_sp; } + const ValueObjectList &GetValueObjectList() const { return m_value_objects; } - void SetValueObjectSP(lldb::ValueObjectSP value_object_sp) { - m_value_object_sp = value_object_sp; - } + ValueObjectList &GetValueObjectList() { return m_value_objects; } lldb::ReturnStatus GetStatus() const; @@ -203,8 +202,8 @@ class CommandReturnObject { lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; - /// An optional return ValueObjectSP. - lldb::ValueObjectSP m_value_object_sp; + /// An optionally empty list of values produced by this command. + ValueObjectList m_value_objects; bool m_did_change_process_state = false; bool m_suppress_immediate_output = false; diff --git a/lldb/include/lldb/ValueObject/ValueObjectList.h b/lldb/include/lldb/ValueObject/ValueObjectList.h index 5d63c65a96e5f..524b66b209c23 100644 --- a/lldb/include/lldb/ValueObject/ValueObjectList.h +++ b/lldb/include/lldb/ValueObject/ValueObjectList.h @@ -22,8 +22,6 @@ class ValueObject; /// A collection of ValueObject values that. class ValueObjectList { public: - const ValueObjectList &operator=(const ValueObjectList &rhs); - void Append(const lldb::ValueObjectSP &val_obj_sp); void Append(const ValueObjectList &valobj_list); diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp index 085bfac57c0a8..e78e213aa23af 100644 --- a/lldb/source/API/SBCommandReturnObject.cpp +++ b/lldb/source/API/SBCommandReturnObject.cpp @@ -13,11 +13,13 @@ #include "lldb/API/SBStream.h" #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBValue.h" +#include "lldb/API/SBValueList.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Instrumentation.h" #include "lldb/Utility/Status.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -358,11 +360,17 @@ void SBCommandReturnObject::SetError(const char *error_cstr) { ref().AppendError(error_cstr); } -SBValue -SBCommandReturnObject::GetReturnValue(lldb::DynamicValueType use_dynamic) { +SBValueList +SBCommandReturnObject::GetValues(lldb::DynamicValueType use_dynamic) { LLDB_INSTRUMENT_VA(this, use_dynamic); - SBValue sb_value; - sb_value.SetSP(ref().GetValueObjectSP(), use_dynamic); - return sb_value; + SBValueList value_list; + for (ValueObjectSP value_object_sp : + ref().GetValueObjectList().GetObjects()) { + SBValue value_sb; + value_sb.SetSP(value_object_sp, use_dynamic); + value_list.Append(value_sb); + } + + return value_list; } diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp index aab99441c63a3..04142427717bd 100644 --- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp +++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp @@ -206,7 +206,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command, expr, exe_scope, valobj_sp, eval_options, &fixed_expression); if (valobj_sp) - result.SetValueObjectSP(valobj_sp); + result.GetValueObjectList().Append(valobj_sp); // Record the position of the expression in the command. std::optional<uint16_t> indent; diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index b0c92d9391b13..18526c4de2cb0 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -434,7 +434,7 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, } if (result_valobj_sp) { - result.SetValueObjectSP(result_valobj_sp); + result.GetValueObjectList().Append(result_valobj_sp); Format format = m_format_options.GetFormat(); diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 96612fdbec6d5..7e42ef2615319 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -152,7 +152,7 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed { return; } - result.SetValueObjectSP(valobj_sp); + result.GetValueObjectList().Append(valobj_sp); DumpValueObjectOptions::DeclPrintingHelper helper = [&valobj_sp](ConstString type, ConstString var, const DumpValueObjectOptions &opts, @@ -318,10 +318,10 @@ class CommandObjectFrameSelect : public CommandObjectParsed { } else if (*m_options.relative_frame_offset > 0) { // I don't want "up 20" where "20" takes you past the top of the stack // to produce an error, but rather to just go to the top. OTOH, start - // by seeing if the requested frame exists, in which case we can avoid + // by seeing if the requested frame exists, in which case we can avoid // counting the stack here... - const uint32_t frame_requested = frame_idx - + *m_options.relative_frame_offset; + const uint32_t frame_requested = + frame_idx + *m_options.relative_frame_offset; StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_requested); if (frame_sp) frame_idx = frame_requested; @@ -516,8 +516,8 @@ may even involve JITing and running code in the target program.)"); if (error.Fail() && (!variable_list || variable_list->GetSize() == 0)) { result.AppendError(error.AsCString()); - } + ValueObjectSP valobj_sp; TypeSummaryImplSP summary_format_sp; @@ -565,6 +565,8 @@ may even involve JITing and running code in the target program.)"); valobj_sp = frame->GetValueObjectForFrameVariable( var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { + result.GetValueObjectList().Append(valobj_sp); + std::string scope_string; if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); @@ -605,6 +607,8 @@ may even involve JITing and running code in the target program.)"); entry.ref(), m_varobj_options.use_dynamic, expr_path_options, var_sp, error); if (valobj_sp) { + result.GetValueObjectList().Append(valobj_sp); + std::string scope_string; if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); @@ -654,6 +658,8 @@ may even involve JITing and running code in the target program.)"); valobj_sp = frame->GetValueObjectForFrameVariable( var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { + result.GetValueObjectList().Append(valobj_sp); + // When dumping all variables, don't print any variables that are // not in scope to avoid extra unneeded output if (valobj_sp->IsInScope()) { @@ -695,6 +701,7 @@ may even involve JITing and running code in the target program.)"); recognized_frame->GetRecognizedArguments(); if (recognized_arg_list) { for (auto &rec_value_sp : recognized_arg_list->GetObjects()) { + result.GetValueObjectList().Append(rec_value_sp); options.SetFormat(m_option_format.GetFormat()); options.SetVariableFormatDisplayLanguage( rec_value_sp->GetPreferredDisplayLanguage()); diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index da50fe04fa2b6..71ddc8d933e1e 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -803,7 +803,9 @@ class CommandObjectTargetVariable : public CommandObjectParsed { protected: void DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, - const VariableList &variable_list, Stream &s) { + const VariableList &variable_list, + CommandReturnObject &result) { + Stream &s = result.GetOutputStream(); if (variable_list.Empty()) return; if (sc.module_sp) { @@ -824,15 +826,16 @@ class CommandObjectTargetVariable : public CommandObjectParsed { ValueObjectSP valobj_sp(ValueObjectVariable::Create( exe_ctx.GetBestExecutionContextScope(), var_sp)); - if (valobj_sp) + if (valobj_sp) { + result.GetValueObjectList().Append(valobj_sp); DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString()); + } } } void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); const size_t argc = args.GetArgumentCount(); - Stream &s = result.GetOutputStream(); if (argc > 0) { for (const Args::ArgEntry &arg : args) { @@ -874,7 +877,7 @@ class CommandObjectTargetVariable : public CommandObjectParsed { m_exe_ctx.GetBestExecutionContextScope(), var_sp); if (valobj_sp) - DumpValueObject(s, var_sp, valobj_sp, + DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg.c_str()); } @@ -903,7 +906,8 @@ class CommandObjectTargetVariable : public CommandObjectParsed { if (comp_unit_varlist_sp) { size_t count = comp_unit_varlist_sp->GetSize(); if (count > 0) { - DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); + DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, + result); success = true; } } @@ -964,7 +968,8 @@ class CommandObjectTargetVariable : public CommandObjectParsed { VariableListSP comp_unit_varlist_sp( sc.comp_unit->GetVariableList(can_create)); if (comp_unit_varlist_sp) - DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); + DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, + result); } else if (sc.module_sp) { // Get all global variables for this module lldb_private::RegularExpression all_globals_regex( @@ -972,7 +977,7 @@ class CommandObjectTargetVariable : public CommandObjectParsed { VariableList variable_list; sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX, variable_list); - DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); + DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result); } } } diff --git a/lldb/source/ValueObject/ValueObjectList.cpp b/lldb/source/ValueObject/ValueObjectList.cpp index a79a040bdf7fd..fdee9579b093b 100644 --- a/lldb/source/ValueObject/ValueObjectList.cpp +++ b/lldb/source/ValueObject/ValueObjectList.cpp @@ -16,12 +16,6 @@ using namespace lldb; using namespace lldb_private; -const ValueObjectList &ValueObjectList::operator=(const ValueObjectList &rhs) { - if (this != &rhs) - m_value_objects = rhs.m_value_objects; - return *this; -} - void ValueObjectList::Append(const ValueObjectSP &val_obj_sp) { m_value_objects.push_back(val_obj_sp); } diff --git a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py index 0fee54eb5fe1d..f8632fd720325 100644 --- a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py +++ b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py @@ -34,8 +34,8 @@ def test_get_command(self): self.assertTrue(res.Succeeded()) self.assertEqual(res.GetCommand(), "help help") - value = res.GetReturnValue(lldb.eNoDynamicValues) - self.assertFalse(value) + value_list = res.GetValues(lldb.eNoDynamicValues) + self.assertEqual(value_list.GetSize(), 0) def test_get_value(self): res = lldb.SBCommandReturnObject() @@ -43,6 +43,6 @@ def test_get_value(self): ci.HandleCommand("p 1 + 1", res) self.assertTrue(res.Succeeded()) - value = res.GetReturnValue(lldb.eNoDynamicValues) - self.assertTrue(value) - self.assertEqual(value.GetValue(), "2") + value_list = res.GetValues(lldb.eNoDynamicValues) + self.assertEqual(value_list.GetSize(), 1) + self.assertEqual(value_list.GetValueAtIndex(0).GetValue(), "2") diff --git a/lldb/test/API/commands/frame/var/TestFrameVar.py b/lldb/test/API/commands/frame/var/TestFrameVar.py index 7211cade5c7c8..d8260a5657618 100644 --- a/lldb/test/API/commands/frame/var/TestFrameVar.py +++ b/lldb/test/API/commands/frame/var/TestFrameVar.py @@ -2,7 +2,6 @@ Make sure the frame variable -g, -a, and -l flags work. """ - import lldb import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test.decorators import * @@ -79,6 +78,14 @@ def do_test(self): self.assertNotIn("test_var", output, "Args found a local") self.assertNotIn("g_var", output, "Args found a global") + value_list = command_result.GetValues(lldb.eNoDynamicValues) + self.assertGreaterEqual(value_list.GetSize(), 2) + value_names = [] + for value in value_list: + value_names.append(value.GetName()) + self.assertIn("argc", value_names) + self.assertIn("argv", value_names) + # Just get locals: result = interp.HandleCommand("frame var -a", command_result) self.assertEqual( diff --git a/lldb/test/API/functionalities/target_var/TestTargetVar.py b/lldb/test/API/functionalities/target_var/TestTargetVar.py index 54b7b77b6773c..0ef3d008e8f19 100644 --- a/lldb/test/API/functionalities/target_var/TestTargetVar.py +++ b/lldb/test/API/functionalities/target_var/TestTargetVar.py @@ -34,3 +34,12 @@ def testTargetVarExpr(self): error=True, substrs=["can't find global variable 'var[0]'"], ) + + command_result = lldb.SBCommandReturnObject() + result = self.ci.HandleCommand("target var", command_result) + value_list = command_result.GetValues(lldb.eNoDynamicValues) + self.assertGreaterEqual(value_list.GetSize(), 2) + value_names = [] + for value in value_list: + value_names.append(value.GetName()) + self.assertIn("i", value_names) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits