Skip to content

Commit 512217c

Browse files
Merge pull request #6986 from augusto2112/cherry-pick-data-format-recursion
Cherry pick data format recursion fix
2 parents f682bc0 + 0da5db4 commit 512217c

File tree

6 files changed

+90
-41
lines changed

6 files changed

+90
-41
lines changed

lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class DumpValueObjectOptions {
2525
enum class Mode { Always, Formatters, Default, Never } m_mode;
2626
uint32_t m_count;
2727

28-
PointerDepth operator--() const {
28+
PointerDepth Decremented() const {
2929
if (m_count > 0)
3030
return PointerDepth{m_mode, m_count - 1};
3131
return PointerDepth{m_mode, m_count};

lldb/include/lldb/DataFormatters/ValueObjectPrinter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ class ValueObjectPrinter {
9191
bool PrintObjectDescriptionIfNeeded(bool value_printed, bool summary_printed);
9292

9393
bool
94-
ShouldPrintChildren(bool is_failed_description,
95-
DumpValueObjectOptions::PointerDepth &curr_ptr_depth);
94+
ShouldPrintChildren(DumpValueObjectOptions::PointerDepth &curr_ptr_depth);
9695

9796
bool ShouldExpandEmptyAggregates();
9897

lldb/source/DataFormatters/ValueObjectPrinter.cpp

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,6 @@ bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const {
523523
}
524524

525525
bool ValueObjectPrinter::ShouldPrintChildren(
526-
bool is_failed_description,
527526
DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
528527
const bool is_ref = IsRef();
529528
const bool is_ptr = IsPtr();
@@ -532,6 +531,10 @@ bool ValueObjectPrinter::ShouldPrintChildren(
532531
if (is_uninit)
533532
return false;
534533

534+
// If we have reached the maximum depth we shouldn't print any more children.
535+
if (HasReachedMaximumDepth())
536+
return false;
537+
535538
// if the user has specified an element count, always print children as it is
536539
// explicit user demand being honored
537540
if (m_options.m_pointer_as_array)
@@ -542,38 +545,37 @@ bool ValueObjectPrinter::ShouldPrintChildren(
542545
if (m_options.m_use_objc)
543546
return false;
544547

545-
if (is_failed_description || !HasReachedMaximumDepth()) {
546-
// We will show children for all concrete types. We won't show pointer
547-
// contents unless a pointer depth has been specified. We won't reference
548-
// contents unless the reference is the root object (depth of zero).
548+
bool print_children = true;
549+
if (TypeSummaryImpl *type_summary = GetSummaryFormatter())
550+
print_children = type_summary->DoesPrintChildren(m_valobj);
549551

550-
// Use a new temporary pointer depth in case we override the current
551-
// pointer depth below...
552+
// We will show children for all concrete types. We won't show pointer
553+
// contents unless a pointer depth has been specified. We won't reference
554+
// contents unless the reference is the root object (depth of zero).
552555

553-
if (is_ptr || is_ref) {
554-
// We have a pointer or reference whose value is an address. Make sure
555-
// that address is not NULL
556-
AddressType ptr_address_type;
557-
if (m_valobj->GetPointerValue(&ptr_address_type) == 0)
558-
return false;
556+
// Use a new temporary pointer depth in case we override the current
557+
// pointer depth below...
559558

560-
const bool is_root_level = m_curr_depth == 0;
559+
if (is_ptr || is_ref) {
560+
// We have a pointer or reference whose value is an address. Make sure
561+
// that address is not NULL
562+
AddressType ptr_address_type;
563+
if (m_valobj->GetPointerValue(&ptr_address_type) == 0)
564+
return false;
561565

562-
if (is_ref && is_root_level) {
563-
// If this is the root object (depth is zero) that we are showing and
564-
// it is a reference, and no pointer depth has been supplied print out
565-
// what it references. Don't do this at deeper depths otherwise we can
566-
// end up with infinite recursion...
567-
return true;
568-
}
566+
const bool is_root_level = m_curr_depth == 0;
569567

570-
return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj,
571-
m_summary);
568+
if (is_ref && is_root_level && print_children) {
569+
// If this is the root object (depth is zero) that we are showing and
570+
// it is a reference, and no pointer depth has been supplied print out
571+
// what it references. Don't do this at deeper depths otherwise we can
572+
// end up with infinite recursion...
573+
return true;
572574
}
573-
574-
return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
575+
return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
575576
}
576-
return false;
577+
578+
return print_children || m_summary.empty();
577579
}
578580

579581
bool ValueObjectPrinter::ShouldExpandEmptyAggregates() {
@@ -610,7 +612,7 @@ void ValueObjectPrinter::PrintChildrenPreamble(bool value_printed,
610612
void ValueObjectPrinter::PrintChild(
611613
ValueObjectSP child_sp,
612614
const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
613-
const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
615+
const uint32_t consumed_summary_depth = m_options.m_pointer_as_array ? 0 : 1;
614616
const bool does_consume_ptr_depth =
615617
((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
616618

@@ -623,15 +625,18 @@ void ValueObjectPrinter::PrintChild(
623625
.SetHideValue(m_options.m_hide_value)
624626
.SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1
625627
? child_options.m_omit_summary_depth -
626-
consumed_depth
628+
consumed_summary_depth
627629
: 0)
628630
.SetElementCount(0);
629631

630632
if (child_sp.get()) {
631-
ValueObjectPrinter child_printer(
632-
child_sp.get(), m_stream, child_options,
633-
does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
634-
m_curr_depth + consumed_depth, m_printed_instance_pointers);
633+
auto ptr_depth = curr_ptr_depth;
634+
if (does_consume_ptr_depth)
635+
ptr_depth = curr_ptr_depth.Decremented();
636+
637+
ValueObjectPrinter child_printer(child_sp.get(), m_stream, child_options,
638+
ptr_depth, m_curr_depth + 1,
639+
m_printed_instance_pointers);
635640
child_printer.PrintValueObject();
636641
}
637642
}
@@ -803,14 +808,10 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
803808

804809
void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
805810
bool summary_printed) {
806-
// This flag controls whether we tried to display a description for this
807-
// object and failed if that happens, we want to display the children if any.
808-
bool is_failed_description =
809-
!PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
811+
PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
810812

811813
DumpValueObjectOptions::PointerDepth curr_ptr_depth = m_ptr_depth;
812-
const bool print_children =
813-
ShouldPrintChildren(is_failed_description, curr_ptr_depth);
814+
const bool print_children = ShouldPrintChildren(curr_ptr_depth);
814815
const bool print_oneline =
815816
(curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types ||
816817
!m_options.m_allow_oneliner_mode || m_options.m_flat_output ||
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Tests that frame variable --depth and --element-count options work correctly
3+
together
4+
"""
5+
import lldb
6+
from lldbsuite.test.lldbtest import *
7+
import lldbsuite.test.lldbutil as lldbutil
8+
9+
10+
class TestFrameVarDepthAndElemCount(TestBase):
11+
def test(self):
12+
"""Test that bool types work in the expression parser"""
13+
self.build()
14+
lldbutil.run_to_source_breakpoint(
15+
self, "break here", lldb.SBFileSpec("main.cpp")
16+
)
17+
18+
# Check that we print 5 elements but only 2 levels deep.
19+
self.expect('frame var --depth 2 --element-count 5 -- c',
20+
substrs=[
21+
'[0] = {\n b ={...}\n }',
22+
'[1] = {\n b ={...}\n }',
23+
'[2] = {\n b ={...}\n }',
24+
'[3] = {\n b ={...}\n }',
25+
'[4] = {\n b ={...}\n }',
26+
])
27+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <cstdio>
2+
3+
struct A {
4+
int i = 42;
5+
};
6+
7+
struct B {
8+
A a;
9+
};
10+
11+
struct C {
12+
B b;
13+
};
14+
15+
int main() {
16+
C *c = new C[5];
17+
puts("break here");
18+
return 0;
19+
}

0 commit comments

Comments
 (0)