diff options
Diffstat (limited to 'lldb/source/Core')
| -rw-r--r-- | lldb/source/Core/CXXFormatterFunctions.cpp | 103 | ||||
| -rw-r--r-- | lldb/source/Core/FormatManager.cpp | 12 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObject.cpp | 80 |
3 files changed, 186 insertions, 9 deletions
diff --git a/lldb/source/Core/CXXFormatterFunctions.cpp b/lldb/source/Core/CXXFormatterFunctions.cpp index cd4e227b86d..e9863de7e70 100644 --- a/lldb/source/Core/CXXFormatterFunctions.cpp +++ b/lldb/source/Core/CXXFormatterFunctions.cpp @@ -158,8 +158,9 @@ ReadUTFBufferAndDumpToStream (uint64_t location, // if not UTF8, I need a conversion function to return proper UTF8 if (origin_encoding != 8 && !ConvertFunction) return false; - const int bufferSPSize = 1024; - const int sourceSize = (bufferSPSize / (origin_encoding >> 2)); + + const int sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); + const int bufferSPSize = sourceSize * (origin_encoding >> 2); Error error; lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0)); @@ -218,6 +219,9 @@ ReadUTFBufferAndDumpToStream (uint64_t location, utf8_data_end_ptr = (UTF8*)data_end_ptr; } + // since we tend to accept partial data (and even partially malformed data) + // we might end up with no NULL terminator before the end_ptr + // hence we need to take a slower route and ensure we stay within boundaries for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++) { if (!*utf8_data_ptr) @@ -290,9 +294,14 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea if (!process_sp) return false; - lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + lldb::addr_t data_addr = 0; + + if (valobj.IsPointerType()) + data_addr = valobj.GetValueAsUnsigned(0); + else if (valobj.IsArrayType()) + data_addr = valobj.GetAddressOf(); - if (!valobj_addr) + if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS) return false; clang::ASTContext* ast = valobj.GetClangAST(); @@ -306,21 +315,21 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea { case 8: // utf 8 - return ReadUTFBufferAndDumpToStream<UTF8, nullptr>(valobj_addr, + return ReadUTFBufferAndDumpToStream<UTF8, nullptr>(data_addr, process_sp, stream, 'L', true); // but use quotes case 16: // utf 16 - return ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(valobj_addr, + return ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(data_addr, process_sp, stream, 'L', true); // but use quotes case 32: // utf 32 - return ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(valobj_addr, + return ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(data_addr, process_sp, stream, 'L', @@ -332,6 +341,86 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea return true; } +// this function extracts information from a libcxx std::basic_string<> +// irregardless of template arguments. it reports the size (in item count not bytes) +// and the location in memory where the string data can be found +static bool +ExtractLibcxxStringInfo (ValueObject& valobj, + ValueObjectSP &location_sp, + uint64_t& size) +{ + ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0})); + if (!D) + return false; + + ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0})); + if (!size_mode) + return false; + + uint64_t size_mode_value(size_mode->GetValueAsUnsigned(0)); + + if ((size_mode_value & 1) == 0) // this means the string is in short-mode and the data is stored inline + { + ValueObjectSP s(D->GetChildAtIndex(1, true)); + if (!s) + return false; + size = ((size_mode_value >> 1) % 256); + location_sp = s->GetChildAtIndex(1, true); + return (location_sp.get() != nullptr); + } + else + { + ValueObjectSP l(D->GetChildAtIndex(0, true)); + if (!l) + return false; + location_sp = l->GetChildAtIndex(2, true); + ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); + if (!size_vo || !location_sp) + return false; + size = size_vo->GetValueAsUnsigned(0); + return true; + } +} + +bool +lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream) +{ + uint64_t size = 0; + ValueObjectSP location_sp((ValueObject*)nullptr); + if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + return false; + if (size == 0) + { + stream.Printf("L\"\""); + return true; + } + if (!location_sp) + return false; + return WCharStringSummaryProvider(*location_sp.get(), stream); +} + +bool +lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream) +{ + uint64_t size = 0; + ValueObjectSP location_sp((ValueObject*)nullptr); + if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + return false; + if (size == 0) + { + stream.Printf("\"\""); + return true; + } + if (!location_sp) + return false; + Error error; + location_sp->ReadPointedString(stream, + error, + 0, // max length is decided by the settings + false); // do not honor array (terminates on first 0 byte even for a char[]) + return error.Success(); +} + template<bool name_entries> bool lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream) diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index 184d65e1cf3..144ddbff37c 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -844,9 +844,12 @@ FormatManager::LoadLibcxxFormatters() .SetHideItemNames(false); #ifndef LLDB_DISABLE_PYTHON - std::string code(" lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)"); - lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str())); + //std::string code(" lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)"); + //lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str())); + lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider")); + lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider")); + TypeCategoryImpl::SharedPointer libcxx_category_sp = GetCategory(m_libcxx_category_name); libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::string"), @@ -854,6 +857,11 @@ FormatManager::LoadLibcxxFormatters() libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"), std_string_summary_sp); + libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::wstring"), + std_wstring_summary_sp); + libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"), + std_wstring_summary_sp); + SyntheticChildren::Flags stl_synth_flags; stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false); diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 2a597b344c7..449e49c0720 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -533,6 +533,86 @@ ValueObject::GetChildAtIndex (uint32_t idx, bool can_create) return child_sp; } +ValueObjectSP +ValueObject::GetChildAtIndexPath (const std::initializer_list<uint32_t>& idxs, + uint32_t* index_of_error) +{ + if (idxs.size() == 0) + return GetSP(); + ValueObjectSP root(GetSP()); + for (uint32_t idx : idxs) + { + root = root->GetChildAtIndex(idx, true); + if (!root) + { + if (index_of_error) + *index_of_error = idx; + return root; + } + } + return root; +} + +ValueObjectSP +ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<uint32_t, bool> >& idxs, + uint32_t* index_of_error) +{ + if (idxs.size() == 0) + return GetSP(); + ValueObjectSP root(GetSP()); + for (std::pair<uint32_t, bool> idx : idxs) + { + root = root->GetChildAtIndex(idx.first, idx.second); + if (!root) + { + if (index_of_error) + *index_of_error = idx.first; + return root; + } + } + return root; +} + +lldb::ValueObjectSP +ValueObject::GetChildAtIndexPath (const std::vector<uint32_t> &idxs, + uint32_t* index_of_error) +{ + if (idxs.size() == 0) + return GetSP(); + ValueObjectSP root(GetSP()); + for (uint32_t idx : idxs) + { + root = root->GetChildAtIndex(idx, true); + if (!root) + { + if (index_of_error) + *index_of_error = idx; + return root; + } + } + return root; +} + +lldb::ValueObjectSP +ValueObject::GetChildAtIndexPath (const std::vector< std::pair<uint32_t, bool> > &idxs, + uint32_t* index_of_error) +{ + if (idxs.size() == 0) + return GetSP(); + ValueObjectSP root(GetSP()); + for (std::pair<uint32_t, bool> idx : idxs) + { + root = root->GetChildAtIndex(idx.first, idx.second); + if (!root) + { + if (index_of_error) + *index_of_error = idx.first; + return root; + } + } + return root; +} + uint32_t ValueObject::GetIndexOfChildWithName (const ConstString &name) { |

