Skip to content

Commit 1b4e578

Browse files
authored
Merge pull request #10065 from swiftlang/cherrypick-stable/20240723-f62f13d5db21
[🍒 stable/20240723] [lldb] Store the return SBValueList in the CommandReturnObject (llvm#127566)
2 parents 22f7040 + b84730a commit 1b4e578

File tree

15 files changed

+130
-22
lines changed

15 files changed

+130
-22
lines changed

lldb/bindings/python/static-binding/LLDBWrapPython.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20113,6 +20113,41 @@ SWIGINTERN PyObject *_wrap_SBCommandReturnObject_SetError(PyObject *self, PyObje
2011320113
}
2011420114

2011520115

20116+
SWIGINTERN PyObject *_wrap_SBCommandReturnObject_GetValues(PyObject *self, PyObject *args) {
20117+
PyObject *resultobj = 0;
20118+
lldb::SBCommandReturnObject *arg1 = (lldb::SBCommandReturnObject *) 0 ;
20119+
lldb::DynamicValueType arg2 ;
20120+
void *argp1 = 0 ;
20121+
int res1 = 0 ;
20122+
int val2 ;
20123+
int ecode2 = 0 ;
20124+
PyObject *swig_obj[2] ;
20125+
lldb::SBValueList result;
20126+
20127+
(void)self;
20128+
if (!SWIG_Python_UnpackTuple(args, "SBCommandReturnObject_GetValues", 2, 2, swig_obj)) SWIG_fail;
20129+
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBCommandReturnObject, 0 | 0 );
20130+
if (!SWIG_IsOK(res1)) {
20131+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBCommandReturnObject_GetValues" "', argument " "1"" of type '" "lldb::SBCommandReturnObject *""'");
20132+
}
20133+
arg1 = reinterpret_cast< lldb::SBCommandReturnObject * >(argp1);
20134+
ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
20135+
if (!SWIG_IsOK(ecode2)) {
20136+
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBCommandReturnObject_GetValues" "', argument " "2"" of type '" "lldb::DynamicValueType""'");
20137+
}
20138+
arg2 = static_cast< lldb::DynamicValueType >(val2);
20139+
{
20140+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
20141+
result = (arg1)->GetValues(arg2);
20142+
SWIG_PYTHON_THREAD_END_ALLOW;
20143+
}
20144+
resultobj = SWIG_NewPointerObj((new lldb::SBValueList(result)), SWIGTYPE_p_lldb__SBValueList, SWIG_POINTER_OWN | 0 );
20145+
return resultobj;
20146+
fail:
20147+
return NULL;
20148+
}
20149+
20150+
2011620151
SWIGINTERN PyObject *_wrap_SBCommandReturnObject___repr__(PyObject *self, PyObject *args) {
2011720152
PyObject *resultobj = 0;
2011820153
lldb::SBCommandReturnObject *arg1 = (lldb::SBCommandReturnObject *) 0 ;
@@ -96661,6 +96696,7 @@ static PyMethodDef SwigMethods[] = {
9666196696
"SBCommandReturnObject_SetError(SBCommandReturnObject self, SBError error, char const * fallback_error_cstr=None)\n"
9666296697
"SBCommandReturnObject_SetError(SBCommandReturnObject self, char const * error_cstr)\n"
9666396698
""},
96699+
{ "SBCommandReturnObject_GetValues", _wrap_SBCommandReturnObject_GetValues, METH_VARARGS, "SBCommandReturnObject_GetValues(SBCommandReturnObject self, lldb::DynamicValueType use_dynamic) -> SBValueList"},
9666496700
{ "SBCommandReturnObject___repr__", _wrap_SBCommandReturnObject___repr__, METH_O, "SBCommandReturnObject___repr__(SBCommandReturnObject self) -> std::string"},
9666596701
{ "SBCommandReturnObject_SetImmediateOutputFile", _wrap_SBCommandReturnObject_SetImmediateOutputFile, METH_VARARGS, "\n"
9666696702
"SBCommandReturnObject_SetImmediateOutputFile(SBCommandReturnObject self, SBFile file)\n"

lldb/bindings/python/static-binding/lldb.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3858,6 +3858,10 @@ def SetError(self, *args):
38583858
"""
38593859
return _lldb.SBCommandReturnObject_SetError(self, *args)
38603860

3861+
def GetValues(self, use_dynamic):
3862+
r"""GetValues(SBCommandReturnObject self, lldb::DynamicValueType use_dynamic) -> SBValueList"""
3863+
return _lldb.SBCommandReturnObject_GetValues(self, use_dynamic)
3864+
38613865
def __repr__(self):
38623866
r"""__repr__(SBCommandReturnObject self) -> std::string"""
38633867
return _lldb.SBCommandReturnObject___repr__(self)

lldb/include/lldb/API/SBCommandReturnObject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ class LLDB_API SBCommandReturnObject {
136136

137137
void SetError(const char *error_cstr);
138138

139+
lldb::SBValueList GetValues(lldb::DynamicValueType use_dynamic);
140+
139141
protected:
140142
friend class SBCommandInterpreter;
141143
friend class SBOptions;

lldb/include/lldb/API/SBValue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ class LLDB_API SBValue {
440440

441441
protected:
442442
friend class SBBlock;
443+
friend class SBCommandReturnObject;
443444
friend class SBFrame;
444445
friend class SBModule;
445446
friend class SBTarget;

lldb/include/lldb/Interpreter/CommandReturnObject.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "lldb/Utility/StreamString.h"
1515
#include "lldb/Utility/StreamTee.h"
1616
#include "lldb/Utility/StructuredData.h"
17+
#include "lldb/ValueObject/ValueObjectList.h"
1718
#include "lldb/lldb-private.h"
1819

1920
#include "llvm/ADT/StringRef.h"
@@ -129,7 +130,7 @@ class CommandReturnObject {
129130
__attribute__((format(printf, 2, 3)));
130131

131132
template <typename... Args>
132-
void AppendMessageWithFormatv(const char *format, Args &&... args) {
133+
void AppendMessageWithFormatv(const char *format, Args &&...args) {
133134
AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str());
134135
}
135136

@@ -139,7 +140,7 @@ class CommandReturnObject {
139140
}
140141

141142
template <typename... Args>
142-
void AppendErrorWithFormatv(const char *format, Args &&... args) {
143+
void AppendErrorWithFormatv(const char *format, Args &&...args) {
143144
AppendError(llvm::formatv(format, std::forward<Args>(args)...).str());
144145
}
145146

@@ -155,6 +156,10 @@ class CommandReturnObject {
155156
return m_diagnostic_indent;
156157
}
157158

159+
const ValueObjectList &GetValueObjectList() const { return m_value_objects; }
160+
161+
ValueObjectList &GetValueObjectList() { return m_value_objects; }
162+
158163
lldb::ReturnStatus GetStatus() const;
159164

160165
void SetStatus(lldb::ReturnStatus status);
@@ -187,6 +192,9 @@ class CommandReturnObject {
187192

188193
lldb::ReturnStatus m_status = lldb::eReturnStatusStarted;
189194

195+
/// An optionally empty list of values produced by this command.
196+
ValueObjectList m_value_objects;
197+
190198
bool m_did_change_process_state = false;
191199
bool m_suppress_immediate_output = false;
192200

lldb/include/lldb/ValueObject/ValueObjectList.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ class ValueObject;
2222
/// A collection of ValueObject values that.
2323
class ValueObjectList {
2424
public:
25-
const ValueObjectList &operator=(const ValueObjectList &rhs);
26-
2725
void Append(const lldb::ValueObjectSP &val_obj_sp);
2826

2927
void Append(const ValueObjectList &valobj_list);

lldb/source/API/SBCommandReturnObject.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
#include "lldb/API/SBFile.h"
1313
#include "lldb/API/SBStream.h"
1414
#include "lldb/API/SBStructuredData.h"
15+
#include "lldb/API/SBValue.h"
16+
#include "lldb/API/SBValueList.h"
1517
#include "lldb/Core/StructuredDataImpl.h"
1618
#include "lldb/Interpreter/CommandReturnObject.h"
1719
#include "lldb/Utility/ConstString.h"
1820
#include "lldb/Utility/Instrumentation.h"
1921
#include "lldb/Utility/Status.h"
22+
#include "lldb/lldb-forward.h"
2023

2124
using namespace lldb;
2225
using namespace lldb_private;
@@ -356,3 +359,18 @@ void SBCommandReturnObject::SetError(const char *error_cstr) {
356359
if (error_cstr)
357360
ref().AppendError(error_cstr);
358361
}
362+
363+
SBValueList
364+
SBCommandReturnObject::GetValues(lldb::DynamicValueType use_dynamic) {
365+
LLDB_INSTRUMENT_VA(this, use_dynamic);
366+
367+
SBValueList value_list;
368+
for (ValueObjectSP value_object_sp :
369+
ref().GetValueObjectList().GetObjects()) {
370+
SBValue value_sb;
371+
value_sb.SetSP(value_object_sp, use_dynamic);
372+
value_list.Append(value_sb);
373+
}
374+
375+
return value_list;
376+
}

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
244244
ExpressionResults expr_result = target.EvaluateExpression(
245245
expr, exe_scope, valobj_sp, eval_options, &fixed_expression);
246246

247+
if (valobj_sp)
248+
result.GetValueObjectList().Append(valobj_sp);
249+
247250
// Record the position of the expression in the command.
248251
std::optional<uint16_t> indent;
249252
if (fixed_expression.empty()) {

lldb/source/Commands/CommandObjectExpression.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
458458
}
459459

460460
if (result_valobj_sp) {
461+
result.GetValueObjectList().Append(result_valobj_sp);
462+
461463
Format format = m_format_options.GetFormat();
462464

463465
if (result_valobj_sp->GetError().Success()) {

lldb/source/Commands/CommandObjectFrame.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed {
152152
return;
153153
}
154154

155+
result.GetValueObjectList().Append(valobj_sp);
155156
DumpValueObjectOptions::DeclPrintingHelper helper =
156157
[&valobj_sp](ConstString type, ConstString var,
157158
const DumpValueObjectOptions &opts,
@@ -317,10 +318,10 @@ class CommandObjectFrameSelect : public CommandObjectParsed {
317318
} else if (*m_options.relative_frame_offset > 0) {
318319
// I don't want "up 20" where "20" takes you past the top of the stack
319320
// to produce an error, but rather to just go to the top. OTOH, start
320-
// by seeing if the requested frame exists, in which case we can avoid
321+
// by seeing if the requested frame exists, in which case we can avoid
321322
// counting the stack here...
322-
const uint32_t frame_requested = frame_idx
323-
+ *m_options.relative_frame_offset;
323+
const uint32_t frame_requested =
324+
frame_idx + *m_options.relative_frame_offset;
324325
StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_requested);
325326
if (frame_sp)
326327
frame_idx = frame_requested;
@@ -515,8 +516,8 @@ may even involve JITing and running code in the target program.)");
515516

516517
if (error.Fail() && (!variable_list || variable_list->GetSize() == 0)) {
517518
result.AppendError(error.AsCString());
518-
519519
}
520+
520521
ValueObjectSP valobj_sp;
521522

522523
TypeSummaryImplSP summary_format_sp;
@@ -564,6 +565,8 @@ may even involve JITing and running code in the target program.)");
564565
valobj_sp = frame->GetValueObjectForFrameVariable(
565566
var_sp, m_varobj_options.use_dynamic);
566567
if (valobj_sp) {
568+
result.GetValueObjectList().Append(valobj_sp);
569+
567570
std::string scope_string;
568571
if (m_option_variable.show_scope)
569572
scope_string = GetScopeString(var_sp).str();
@@ -604,6 +607,8 @@ may even involve JITing and running code in the target program.)");
604607
entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
605608
var_sp, error);
606609
if (valobj_sp) {
610+
result.GetValueObjectList().Append(valobj_sp);
611+
607612
std::string scope_string;
608613
if (m_option_variable.show_scope)
609614
scope_string = GetScopeString(var_sp).str();
@@ -653,6 +658,8 @@ may even involve JITing and running code in the target program.)");
653658
valobj_sp = frame->GetValueObjectForFrameVariable(
654659
var_sp, m_varobj_options.use_dynamic);
655660
if (valobj_sp) {
661+
result.GetValueObjectList().Append(valobj_sp);
662+
656663
// When dumping all variables, don't print any variables that are
657664
// not in scope to avoid extra unneeded output
658665
if (valobj_sp->IsInScope()) {
@@ -694,6 +701,7 @@ may even involve JITing and running code in the target program.)");
694701
recognized_frame->GetRecognizedArguments();
695702
if (recognized_arg_list) {
696703
for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
704+
result.GetValueObjectList().Append(rec_value_sp);
697705
options.SetFormat(m_option_format.GetFormat());
698706
options.SetVariableFormatDisplayLanguage(
699707
rec_value_sp->GetPreferredDisplayLanguage());

lldb/source/Commands/CommandObjectTarget.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,9 @@ class CommandObjectTargetVariable : public CommandObjectParsed {
803803
protected:
804804
void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
805805
const SymbolContext &sc,
806-
const VariableList &variable_list, Stream &s) {
806+
const VariableList &variable_list,
807+
CommandReturnObject &result) {
808+
Stream &s = result.GetOutputStream();
807809
if (variable_list.Empty())
808810
return;
809811
if (sc.module_sp) {
@@ -824,15 +826,16 @@ class CommandObjectTargetVariable : public CommandObjectParsed {
824826
ValueObjectSP valobj_sp(ValueObjectVariable::Create(
825827
exe_ctx.GetBestExecutionContextScope(), var_sp));
826828

827-
if (valobj_sp)
829+
if (valobj_sp) {
830+
result.GetValueObjectList().Append(valobj_sp);
828831
DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
832+
}
829833
}
830834
}
831835

832836
void DoExecute(Args &args, CommandReturnObject &result) override {
833837
Target *target = m_exe_ctx.GetTargetPtr();
834838
const size_t argc = args.GetArgumentCount();
835-
Stream &s = result.GetOutputStream();
836839

837840
if (argc > 0) {
838841
for (const Args::ArgEntry &arg : args) {
@@ -874,7 +877,7 @@ class CommandObjectTargetVariable : public CommandObjectParsed {
874877
m_exe_ctx.GetBestExecutionContextScope(), var_sp);
875878

876879
if (valobj_sp)
877-
DumpValueObject(s, var_sp, valobj_sp,
880+
DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,
878881
use_var_name ? var_sp->GetName().GetCString()
879882
: arg.c_str());
880883
}
@@ -903,7 +906,8 @@ class CommandObjectTargetVariable : public CommandObjectParsed {
903906
if (comp_unit_varlist_sp) {
904907
size_t count = comp_unit_varlist_sp->GetSize();
905908
if (count > 0) {
906-
DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
909+
DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
910+
result);
907911
success = true;
908912
}
909913
}
@@ -964,15 +968,16 @@ class CommandObjectTargetVariable : public CommandObjectParsed {
964968
VariableListSP comp_unit_varlist_sp(
965969
sc.comp_unit->GetVariableList(can_create));
966970
if (comp_unit_varlist_sp)
967-
DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
971+
DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
972+
result);
968973
} else if (sc.module_sp) {
969974
// Get all global variables for this module
970975
lldb_private::RegularExpression all_globals_regex(
971976
llvm::StringRef(".")); // Any global with at least one character
972977
VariableList variable_list;
973978
sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
974979
variable_list);
975-
DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
980+
DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);
976981
}
977982
}
978983
}

lldb/source/ValueObject/ValueObjectList.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
using namespace lldb;
1717
using namespace lldb_private;
1818

19-
const ValueObjectList &ValueObjectList::operator=(const ValueObjectList &rhs) {
20-
if (this != &rhs)
21-
m_value_objects = rhs.m_value_objects;
22-
return *this;
23-
}
24-
2519
void ValueObjectList::Append(const ValueObjectSP &val_obj_sp) {
2620
m_value_objects.push_back(val_obj_sp);
2721
}

lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,16 @@ def test_get_command(self):
3333
ci.HandleCommand("help help", res)
3434
self.assertTrue(res.Succeeded())
3535
self.assertEqual(res.GetCommand(), "help help")
36+
37+
value_list = res.GetValues(lldb.eNoDynamicValues)
38+
self.assertEqual(value_list.GetSize(), 0)
39+
40+
def test_get_value(self):
41+
res = lldb.SBCommandReturnObject()
42+
ci = self.dbg.GetCommandInterpreter()
43+
ci.HandleCommand("p 1 + 1", res)
44+
self.assertTrue(res.Succeeded())
45+
46+
value_list = res.GetValues(lldb.eNoDynamicValues)
47+
self.assertEqual(value_list.GetSize(), 1)
48+
self.assertEqual(value_list.GetValueAtIndex(0).GetValue(), "2")

lldb/test/API/commands/frame/var/TestFrameVar.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Make sure the frame variable -g, -a, and -l flags work.
33
"""
44

5-
65
import lldb
76
import lldbsuite.test.lldbutil as lldbutil
87
from lldbsuite.test.decorators import *
@@ -79,6 +78,14 @@ def do_test(self):
7978
self.assertNotIn("test_var", output, "Args found a local")
8079
self.assertNotIn("g_var", output, "Args found a global")
8180

81+
value_list = command_result.GetValues(lldb.eNoDynamicValues)
82+
self.assertGreaterEqual(value_list.GetSize(), 2)
83+
value_names = []
84+
for value in value_list:
85+
value_names.append(value.GetName())
86+
self.assertIn("argc", value_names)
87+
self.assertIn("argv", value_names)
88+
8289
# Just get locals:
8390
result = interp.HandleCommand("frame var -a", command_result)
8491
self.assertEqual(

lldb/test/API/functionalities/target_var/TestTargetVar.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,12 @@ def testTargetVarExpr(self):
3434
error=True,
3535
substrs=["can't find global variable 'var[0]'"],
3636
)
37+
38+
command_result = lldb.SBCommandReturnObject()
39+
result = self.ci.HandleCommand("target var", command_result)
40+
value_list = command_result.GetValues(lldb.eNoDynamicValues)
41+
self.assertGreaterEqual(value_list.GetSize(), 2)
42+
value_names = []
43+
for value in value_list:
44+
value_names.append(value.GetName())
45+
self.assertIn("i", value_names)

0 commit comments

Comments
 (0)