Loading lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +54 −49 Original line number Diff line number Diff line Loading @@ -468,22 +468,20 @@ enum LibcxxStringLayoutMode { eLibcxxStringLayoutModeInvalid = 0xffff }; // this function abstracts away the layout and mode details of a libc++ string // and returns the address of the data and the size ready for callers to // consume static bool ExtractLibcxxStringInfo(ValueObject &valobj, ValueObjectSP &location_sp, uint64_t &size) { /// Determine the size in bytes of \p valobj (a libc++ std::string object) and /// extract its data payload. Return the size + payload pair. static llvm::Optional<std::pair<uint64_t, ValueObjectSP>> ExtractLibcxxStringInfo(ValueObject &valobj) { ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); if (!D) return false; return {}; ValueObjectSP layout_decider( D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) return false; return {}; ConstString g_data_name("__data_"); ConstString g_size_name("__size_"); Loading @@ -497,13 +495,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (layout == eLibcxxStringLayoutModeDSC) { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); if (!size_mode) return false; return {}; if (size_mode->GetName() != g_size_name) { // we are hitting the padding structure, move along size_mode = D->GetChildAtIndexPath({1, 1, 1}); if (!size_mode) return false; return {}; } size_mode_value = (size_mode->GetValueAsUnsigned(0)); Loading @@ -511,7 +509,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, } else { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); if (!size_mode) return false; return {}; size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 1) == 0); Loading @@ -520,10 +518,10 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (short_mode) { ValueObjectSP s(D->GetChildAtIndex(1, true)); if (!s) return false; location_sp = s->GetChildAtIndex( return {}; ValueObjectSP location_sp = s->GetChildAtIndex( (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); size = (layout == eLibcxxStringLayoutModeDSC) const uint64_t size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256); Loading @@ -534,16 +532,17 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, const llvm::Optional<uint64_t> max_bytes = location_sp->GetCompilerType().GetByteSize( exe_ctx.GetBestExecutionContextScope()); if (!max_bytes || size > *max_bytes) return false; if (!max_bytes || size > *max_bytes || !location_sp) return {}; return std::make_pair(size, location_sp); } return (location_sp.get() != nullptr); } else { ValueObjectSP l(D->GetChildAtIndex(0, true)); if (!l) return false; return {}; // we can use the layout_decider object as the data pointer location_sp = (layout == eLibcxxStringLayoutModeDSC) ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC) ? layout_decider : l->GetChildAtIndex(2, true); ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); Loading @@ -551,22 +550,26 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0; ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true)); if (!size_vo || !location_sp || !capacity_vo) return false; size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); const uint64_t cap = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); if (size == LLDB_INVALID_OFFSET || cap == LLDB_INVALID_OFFSET || cap < size) return false; return true; } return {}; const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); const uint64_t capacity = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET || capacity < size) return {}; return std::make_pair(size, location_sp); } bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { uint64_t size = 0; ValueObjectSP location_sp; if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) auto string_info = ExtractLibcxxStringInfo(valobj); if (!string_info) return false; uint64_t size; ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("L\"\""); return true; Loading @@ -574,10 +577,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( if (!location_sp) return false; DataExtractor extractor; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { Loading @@ -585,6 +586,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetIsTruncated(true); } } DataExtractor extractor; const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); if (bytes_read < size) return false; Loading Loading @@ -632,10 +635,13 @@ template <StringPrinter::StringElementType element_type> bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token) { uint64_t size = 0; ValueObjectSP location_sp; if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) auto string_info = ExtractLibcxxStringInfo(valobj); if (!string_info) return false; uint64_t size; ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("\"\""); return true; Loading @@ -646,7 +652,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); DataExtractor extractor; if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { Loading @@ -654,18 +659,18 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, options.SetIsTruncated(true); } } DataExtractor extractor; const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); if (bytes_read < size) return false; options.SetData(extractor); options.SetStream(&stream); if (prefix_token.empty()) options.SetPrefixToken(nullptr); else options.SetPrefixToken(prefix_token); options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); Loading Loading
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +54 −49 Original line number Diff line number Diff line Loading @@ -468,22 +468,20 @@ enum LibcxxStringLayoutMode { eLibcxxStringLayoutModeInvalid = 0xffff }; // this function abstracts away the layout and mode details of a libc++ string // and returns the address of the data and the size ready for callers to // consume static bool ExtractLibcxxStringInfo(ValueObject &valobj, ValueObjectSP &location_sp, uint64_t &size) { /// Determine the size in bytes of \p valobj (a libc++ std::string object) and /// extract its data payload. Return the size + payload pair. static llvm::Optional<std::pair<uint64_t, ValueObjectSP>> ExtractLibcxxStringInfo(ValueObject &valobj) { ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); if (!D) return false; return {}; ValueObjectSP layout_decider( D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) return false; return {}; ConstString g_data_name("__data_"); ConstString g_size_name("__size_"); Loading @@ -497,13 +495,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (layout == eLibcxxStringLayoutModeDSC) { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); if (!size_mode) return false; return {}; if (size_mode->GetName() != g_size_name) { // we are hitting the padding structure, move along size_mode = D->GetChildAtIndexPath({1, 1, 1}); if (!size_mode) return false; return {}; } size_mode_value = (size_mode->GetValueAsUnsigned(0)); Loading @@ -511,7 +509,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, } else { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); if (!size_mode) return false; return {}; size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 1) == 0); Loading @@ -520,10 +518,10 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (short_mode) { ValueObjectSP s(D->GetChildAtIndex(1, true)); if (!s) return false; location_sp = s->GetChildAtIndex( return {}; ValueObjectSP location_sp = s->GetChildAtIndex( (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); size = (layout == eLibcxxStringLayoutModeDSC) const uint64_t size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256); Loading @@ -534,16 +532,17 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, const llvm::Optional<uint64_t> max_bytes = location_sp->GetCompilerType().GetByteSize( exe_ctx.GetBestExecutionContextScope()); if (!max_bytes || size > *max_bytes) return false; if (!max_bytes || size > *max_bytes || !location_sp) return {}; return std::make_pair(size, location_sp); } return (location_sp.get() != nullptr); } else { ValueObjectSP l(D->GetChildAtIndex(0, true)); if (!l) return false; return {}; // we can use the layout_decider object as the data pointer location_sp = (layout == eLibcxxStringLayoutModeDSC) ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC) ? layout_decider : l->GetChildAtIndex(2, true); ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); Loading @@ -551,22 +550,26 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0; ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true)); if (!size_vo || !location_sp || !capacity_vo) return false; size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); const uint64_t cap = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); if (size == LLDB_INVALID_OFFSET || cap == LLDB_INVALID_OFFSET || cap < size) return false; return true; } return {}; const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); const uint64_t capacity = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET || capacity < size) return {}; return std::make_pair(size, location_sp); } bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { uint64_t size = 0; ValueObjectSP location_sp; if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) auto string_info = ExtractLibcxxStringInfo(valobj); if (!string_info) return false; uint64_t size; ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("L\"\""); return true; Loading @@ -574,10 +577,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( if (!location_sp) return false; DataExtractor extractor; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { Loading @@ -585,6 +586,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetIsTruncated(true); } } DataExtractor extractor; const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); if (bytes_read < size) return false; Loading Loading @@ -632,10 +635,13 @@ template <StringPrinter::StringElementType element_type> bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token) { uint64_t size = 0; ValueObjectSP location_sp; if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) auto string_info = ExtractLibcxxStringInfo(valobj); if (!string_info) return false; uint64_t size; ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("\"\""); return true; Loading @@ -646,7 +652,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); DataExtractor extractor; if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { Loading @@ -654,18 +659,18 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, options.SetIsTruncated(true); } } DataExtractor extractor; const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); if (bytes_read < size) return false; options.SetData(extractor); options.SetStream(&stream); if (prefix_token.empty()) options.SetPrefixToken(nullptr); else options.SetPrefixToken(prefix_token); options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); Loading