diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/DataExtractor.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 24 | ||||
-rw-r--r-- | lldb/source/Core/FormatManager.cpp | 30 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 190 |
4 files changed, 209 insertions, 42 deletions
diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 4cc98f31a65..aea0c471fcb 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -1610,8 +1610,11 @@ DataExtractor::Dump s->Printf("0x%8.8x", GetU32 (&offset)); break; - case eFormatVectorOfChar: - s->PutChar('{'); +// please keep the single-item formats below in sync with FormatManager::GetSingleItemFormat +// if you fail to do so, users will start getting different outputs depending on internal +// implementation details they should not care about || + case eFormatVectorOfChar: // || + s->PutChar('{'); // \/ offset = Dump (s, start_offset, eFormatCharArray, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 9b34331e84f..2c36dbb8c66 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -694,6 +694,7 @@ TestPromptFormats (StackFrame *frame) } } +// FIXME this should eventually be replaced by proper use of LLDB logging facilities //#define VERBOSE_FORMATPROMPT_OUTPUT #ifdef VERBOSE_FORMATPROMPT_OUTPUT #define IFERROR_PRINT_IT if (error.Fail()) \ @@ -1090,14 +1091,29 @@ Debugger::FormatPrompt IFERROR_PRINT_IT do_deref_pointer = false; } + + bool is_array = ClangASTContext::IsArrayType(target->GetClangType()); + bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); + + if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eDisplayValue) // this should be wrong, but there are some exceptions + { +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("I am into array || pointer && !range\n"); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + // try to use the special cases + var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); + if (!var_success) + s << "<invalid, please use [] operator>"; +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("outcome was : %s\n", var_success ? "good" : "bad"); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + break; + } if (!is_array_range) var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); else - { - bool is_array = ClangASTContext::IsArrayType(target->GetClangType()); - bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); - + { if (!is_array && !is_pointer) break; diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index ece30068e4d..040b9cd9ebd 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -187,3 +187,33 @@ FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Delete(const char* ty } return false; } + +lldb::Format +FormatManager::GetSingleItemFormat(lldb::Format vector_format) +{ + switch(vector_format) + { + case eFormatVectorOfChar: + return eFormatCharArray; + + case eFormatVectorOfSInt8: + case eFormatVectorOfSInt16: + case eFormatVectorOfSInt32: + case eFormatVectorOfSInt64: + return eFormatDecimal; + + case eFormatVectorOfUInt8: + case eFormatVectorOfUInt16: + case eFormatVectorOfUInt32: + case eFormatVectorOfUInt64: + case eFormatVectorOfUInt128: + return eFormatHex; + + case eFormatVectorOfFloat32: + case eFormatVectorOfFloat64: + return eFormatFloat; + + default: + return lldb::eFormatInvalid; + } +} diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index d39b836f021..d8e0e0f8ef8 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -40,8 +40,11 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RefCounter.h" + using namespace lldb; using namespace lldb_private; +using namespace lldb_utility; static lldb::user_id_t g_value_obj_uid = 0; @@ -78,7 +81,8 @@ ValueObject::ValueObject (ValueObject &parent) : m_last_format_mgr_revision(0), m_last_summary_format(), m_last_value_format(), - m_forced_summary_format() + m_forced_summary_format(), + m_dump_printable_counter(0) { m_manager->ManageObject(this); } @@ -116,7 +120,8 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) : m_last_format_mgr_revision(0), m_last_summary_format(), m_last_value_format(), - m_forced_summary_format() + m_forced_summary_format(), + m_dump_printable_counter(0) { m_manager = new ValueObjectManager(); m_manager->ManageObject (this); @@ -752,11 +757,13 @@ ValueObject::IsCStringContainer(bool check_pointer) void ValueObject::ReadPointedString(Stream& s, Error& error, - uint32_t max_length) + uint32_t max_length, + bool honor_array, + lldb::Format item_format) { if (max_length == 0) - max_length = 128; // this should be a setting, or a formatting parameter + max_length = 128; // FIXME this should be a setting, or a formatting parameter clang_type_t clang_type = GetClangType(); clang_type_t elem_or_pointee_clang_type; @@ -781,14 +788,10 @@ ValueObject::ReadPointedString(Stream& s, { // We have an array cstr_len = ClangASTContext::GetArraySize (clang_type); - if (cstr_len > max_length) // TODO: make cap a setting + if (cstr_len > max_length) { - cstr_len = ClangASTContext::GetArraySize (clang_type); - if (cstr_len > max_length) // TODO: make cap a setting - { - capped_data = true; - cstr_len = max_length; - } + capped_data = true; + cstr_len = max_length; } cstr_address = GetAddressOf (cstr_address_type, true); } @@ -803,9 +806,8 @@ ValueObject::ReadPointedString(Stream& s, DataExtractor data; size_t bytes_read = 0; std::vector<char> data_buffer; - Error error; bool prefer_file_cache = false; - if (cstr_len > 0) + if (cstr_len > 0 && honor_array) { data_buffer.resize(cstr_len); data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder()); @@ -819,7 +821,7 @@ ValueObject::ReadPointedString(Stream& s, s << '"'; data.Dump (&s, 0, // Start offset in "data" - eFormatCharArray, // Print as characters + item_format, 1, // Size of item (1 byte for a char!) bytes_read, // How many bytes to print? UINT32_MAX, // num per line @@ -833,7 +835,8 @@ ValueObject::ReadPointedString(Stream& s, } else { - const size_t k_max_buf_size = 256; + cstr_len = max_length; + const size_t k_max_buf_size = 64; data_buffer.resize (k_max_buf_size + 1); // NULL terminate in case we don't get the entire C string data_buffer.back() = '\0'; @@ -852,10 +855,12 @@ ValueObject::ReadPointedString(Stream& s, break; if (len > bytes_read) len = bytes_read; + if (len > cstr_len) + len = cstr_len; data.Dump (&s, 0, // Start offset in "data" - eFormatCharArray, // Print as characters + item_format, 1, // Size of item (1 byte for a char!) len, // How many bytes to print? UINT32_MAX, // num per line @@ -865,6 +870,12 @@ ValueObject::ReadPointedString(Stream& s, if (len < k_max_buf_size) break; + if (len >= cstr_len) + { + s << "..."; + break; + } + cstr_len -= len; cstr_so_addr.Slide (k_max_buf_size); } s << '"'; @@ -1016,6 +1027,9 @@ const char * ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, lldb::Format custom_format) { + + RefCounter ref(&m_dump_printable_counter); + if(custom_format != lldb::eFormatInvalid) SetFormat(custom_format); @@ -1034,18 +1048,18 @@ ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_d break; } - if (!return_value) + // this code snippet might lead to endless recursion, thus we use a RefCounter here to + // check that we are not looping endlessly + if (!return_value && (m_dump_printable_counter < 3)) { // try to pick the other choice if (val_obj_display == eDisplayValue) return_value = GetSummaryAsCString(); else if (val_obj_display == eDisplaySummary) return_value = GetValueAsCString(); - else - return_value = ""; } - return (return_value ? return_value : ""); + return (return_value ? return_value : "<error>"); } @@ -1054,25 +1068,129 @@ ValueObject::DumpPrintableRepresentation(Stream& s, ValueObjectRepresentationStyle val_obj_display, lldb::Format custom_format) { + + clang_type_t elem_or_pointee_type; + Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type)); - if (IsCStringContainer(true) && - val_obj_display == ValueObject::eDisplayValue && - custom_format == lldb::eFormatCString) + if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) + && val_obj_display == ValueObject::eDisplayValue) { - Error error; - ReadPointedString(s, error); - return error.Success(); - } - else - { - const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format); - if(targetvalue) - s.PutCString(targetvalue); - bool var_success = (targetvalue != NULL); - if(custom_format != eFormatInvalid) - SetFormat(eFormatDefault); - return var_success; + // when being asked to get a printable display an array or pointer type directly, + // try to "do the right thing" + + if (IsCStringContainer(true) && + (custom_format == lldb::eFormatCString || + custom_format == lldb::eFormatCharArray || + custom_format == lldb::eFormatChar || + custom_format == lldb::eFormatVectorOfChar)) // print char[] & char* directly + { + Error error; + ReadPointedString(s, + error, + 0, + (custom_format == lldb::eFormatVectorOfChar) || + (custom_format == lldb::eFormatCharArray)); + return !error.Fail(); + } + + if (custom_format == lldb::eFormatEnum) + return false; + + // this only works for arrays, because I have no way to know when + // the pointed memory ends, and no special \0 end of data marker + if (flags.Test(ClangASTContext::eTypeIsArray)) + { + if ((custom_format == lldb::eFormatBytes) || + (custom_format == lldb::eFormatBytesWithASCII)) + { + uint32_t count = GetNumChildren(); + + s << '['; + for (uint32_t low = 0; low < count; low++) + { + + if (low) + s << ','; + + ValueObjectSP child = GetChildAtIndex(low,true); + if (!child.get()) + { + s << "<error>"; + continue; + } + child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format); + } + + s << ']'; + + return true; + } + + if ((custom_format == lldb::eFormatVectorOfChar) || + (custom_format == lldb::eFormatVectorOfFloat32) || + (custom_format == lldb::eFormatVectorOfFloat64) || + (custom_format == lldb::eFormatVectorOfSInt16) || + (custom_format == lldb::eFormatVectorOfSInt32) || + (custom_format == lldb::eFormatVectorOfSInt64) || + (custom_format == lldb::eFormatVectorOfSInt8) || + (custom_format == lldb::eFormatVectorOfUInt128) || + (custom_format == lldb::eFormatVectorOfUInt16) || + (custom_format == lldb::eFormatVectorOfUInt32) || + (custom_format == lldb::eFormatVectorOfUInt64) || + (custom_format == lldb::eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly + { + uint32_t count = GetNumChildren(); + + lldb::Format format = FormatManager::GetSingleItemFormat(custom_format); + + s << '['; + for (uint32_t low = 0; low < count; low++) + { + + if (low) + s << ','; + + ValueObjectSP child = GetChildAtIndex(low,true); + if (!child.get()) + { + s << "<error>"; + continue; + } + child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format); + } + + s << ']'; + + return true; + } + } + + if ((custom_format == lldb::eFormatBoolean) || + (custom_format == lldb::eFormatBinary) || + (custom_format == lldb::eFormatChar) || + (custom_format == lldb::eFormatCharPrintable) || + (custom_format == lldb::eFormatComplexFloat) || + (custom_format == lldb::eFormatDecimal) || + (custom_format == lldb::eFormatHex) || + (custom_format == lldb::eFormatFloat) || + (custom_format == lldb::eFormatOctal) || + (custom_format == lldb::eFormatOSType) || + (custom_format == lldb::eFormatUnicode16) || + (custom_format == lldb::eFormatUnicode32) || + (custom_format == lldb::eFormatUnsigned) || + (custom_format == lldb::eFormatPointer) || + (custom_format == lldb::eFormatComplexInteger) || + (custom_format == lldb::eFormatComplex) || + (custom_format == lldb::eFormatDefault)) // use the [] operator + return false; } + const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format); + if(targetvalue) + s.PutCString(targetvalue); + bool var_success = (targetvalue != NULL); + if(custom_format != eFormatInvalid) + SetFormat(eFormatDefault); + return var_success; } addr_t |