diff --git a/lldb/bindings/interface/SBTarget.i b/lldb/bindings/interface/SBTarget.i --- a/lldb/bindings/interface/SBTarget.i +++ b/lldb/bindings/interface/SBTarget.i @@ -412,6 +412,9 @@ uint32_t GetCodeByteSize (); + uint32_t + GetMaximumNumberOfChildrenToDisplay() const; + lldb::SBError SetSectionLoadAddress (lldb::SBSection section, lldb::addr_t section_base_addr); diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -9,6 +9,14 @@ # before relying on these formatters to do the right thing for your setup +def ForwardListSummaryProvider(valobj, dict): + list_capping_size = valobj.GetTarget().GetMaximumNumberOfChildrenToDisplay() + text = "size=" + str(valobj.GetNumChildren()) + if valobj.GetNumChildren() > list_capping_size: + return "(capped) " + text + else: + return text + class AbstractListSynthProvider: def __init__(self, valobj, dict, has_prev): ''' @@ -20,6 +28,7 @@ self.valobj = valobj self.count = None self.has_prev = has_prev + self.list_capping_size = self.valobj.GetTarget().GetMaximumNumberOfChildrenToDisplay() logger >> "Providing synthetic children for a list named " + \ str(valobj.GetName()) @@ -99,6 +108,9 @@ '_M_next').GetValueAsUnsigned(0) != self.get_end_of_list_address(): size = size + 1 current = current.GetChildMemberWithName('_M_next') + # In case of forward_list capping size is the limit of the children to be displayed + if not self.has_prev and size >= self.list_capping_size: + break return size except: logger >> "Error determining the size" diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -336,6 +336,11 @@ /// unit from the Architecture's code bus uint32_t GetCodeByteSize(); + /// Gets the target.max-children-count value + /// It should be used to limit the number of + /// children of large data structures to be displayed. + uint32_t GetMaximumNumberOfChildrenToDisplay() const; + /// Set the base load address for a module section. /// /// \param[in] section diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1745,6 +1745,16 @@ return 0; } +uint32_t SBTarget::GetMaximumNumberOfChildrenToDisplay() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBTarget, GetMaximumNumberOfChildrenToDisplay); + + TargetSP target_sp(GetSP()); + if(target_sp){ + return target_sp->GetMaximumNumberOfChildrenToDisplay(); + } + return 0; +} + uint32_t SBTarget::GetAddressByteSize() { LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTarget, GetAddressByteSize); @@ -2679,6 +2689,7 @@ LLDB_REGISTER_METHOD(const char *, SBTarget, GetTriple, ()); LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetDataByteSize, ()); LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetCodeByteSize, ()); + LLDB_REGISTER_METHOD_CONST(uint32_t, SBTarget, GetMaximumNumberOfChildrenToDisplay,()); LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetAddressByteSize, ()); LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, GetModuleAtIndex, (uint32_t)); diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -961,7 +961,7 @@ cpp_category_sp->GetRegexTypeSummariesContainer()->Add( RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"), TypeSummaryImplSP( - new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider"))); AddCXXSynthetic( cpp_category_sp, diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/TestDataFormatterGenericForwardList.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/TestDataFormatterGenericForwardList.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/TestDataFormatterGenericForwardList.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/TestDataFormatterGenericForwardList.py @@ -52,6 +52,38 @@ '[4] = 55555', '}']) + self.expect("settings show target.max-children-count", matching=True, + substrs=['target.max-children-count (int) = 256']) + + self.expect("frame variable thousand_elts",matching=False, + substrs=[ + '[256]', + '[333]', + '[444]', + '[555]', + '[666]', + '...' + ]) + self.runCmd( + "settings set target.max-children-count 3", + check=False) + + self.expect("frame variable thousand_elts",matching=False, + substrs=[ + '[3]', + '[4]', + '[5]', + ]) + + self.expect("frame variable thousand_elts",matching=True, + substrs=[ + 'size=256', + '[0]', + '[1]', + '[2]', + '...' + ]) + @add_test_categories(["libstdcxx"]) def test_libstdcpp(self): self.do_test(USE_LIBSTDCPP) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/main.cpp --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/forward_list/main.cpp @@ -2,6 +2,9 @@ int main() { std::forward_list empty{}, one_elt{47}, - five_elts{1, 22, 333, 4444, 55555}; + five_elts{1, 22, 333, 4444, 55555}, thousand_elts{}; + for(int i = 0; i<1000;i++){ + thousand_elts.push_front(i); + } return 0; // break here }