[Lldb-commits] [lldb] r135007 - in /lldb/trunk: include/lldb/Core/FormatManager.h include/lldb/Core/ValueObject.h lldb.xcodeproj/project.pbxproj source/Core/DataExtractor.cpp source/Core/Debugger.cpp source/Core/FormatManager.cpp source/Core/ValueObject.cpp test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py www/varformats.html
Enrico Granata
granata.enrico at gmail.com
Tue Jul 12 15:56:10 PDT 2011
Author: enrico
Date: Tue Jul 12 17:56:10 2011
New Revision: 135007
URL: http://llvm.org/viewvc/llvm-project?rev=135007&view=rev
Log:
smarter summary strings:
- formats %s %char[] %c and %a now work to print 0-terminated c-strings if they are applied to a char* or char[] even without the [] operator (e.g. ${var%s})
- array formats (char[], intN[], ..) now work when applied to an array of a scalar type even without the [] operator (e.g. ${var%int32_t[]})
LLDB will not crash because of endless loop when trying to obtain a summary for an object that has no value and references itself in its summary string
In many cases, a wrong summary string will now display an "<error>" message instead of giving out an empty string
Modified:
lldb/trunk/include/lldb/Core/FormatManager.h
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Core/DataExtractor.cpp
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/FormatManager.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
lldb/trunk/www/varformats.html
Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Tue Jul 12 17:56:10 2011
@@ -499,6 +499,11 @@
static const char *
GetFormatAsCString (lldb::Format format);
+ // when DataExtractor dumps a vectorOfT, it uses a predefined format for each item
+ // this method returns it, or eFormatInvalid if vector_format is not a vectorOf
+ static lldb::Format
+ GetSingleItemFormat(lldb::Format vector_format);
+
void
Changed()
{
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Tue Jul 12 17:56:10 2011
@@ -602,7 +602,9 @@
void
ReadPointedString(Stream& s,
Error& error,
- uint32_t max_length = 0);
+ uint32_t max_length = 0,
+ bool honor_array = true,
+ lldb::Format item_format = lldb::eFormatCharArray);
bool
GetIsConstant () const
@@ -741,6 +743,8 @@
m_is_array_item_for_pointer:1,
m_is_bitfield_for_scalar:1;
+ // used to prevent endless looping into GetpPrintableRepresentation()
+ uint32_t m_dump_printable_counter;
friend class ClangExpressionDeclMap; // For GetValue
friend class ClangExpressionVariable; // For SetName
friend class Target; // For SetName
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Jul 12 17:56:10 2011
@@ -403,6 +403,7 @@
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; };
4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; };
9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */; };
+ 94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94611EB113CCA4A4003A22AF /* RefCounter.cpp */; };
9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; };
9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; };
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1170,6 +1171,8 @@
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
9415F61613B2C0DC00A52B36 /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatManager.h; path = include/lldb/Core/FormatManager.h; sourceTree = "<group>"; };
9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = "<group>"; };
+ 94611EAF13CCA363003A22AF /* RefCounter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RefCounter.h; path = include/lldb/Utility/RefCounter.h; sourceTree = "<group>"; };
+ 94611EB113CCA4A4003A22AF /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RefCounter.cpp; path = source/Utility/RefCounter.cpp; sourceTree = "<group>"; };
9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = "<group>"; };
9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = "<group>"; };
9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = "<group>"; };
@@ -1780,6 +1783,8 @@
isa = PBXGroup;
children = (
264723A511FA076E00DE380C /* CleanUp.h */,
+ 94611EAF13CCA363003A22AF /* RefCounter.h */,
+ 94611EB113CCA4A4003A22AF /* RefCounter.cpp */,
261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */,
4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */,
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */,
@@ -3265,6 +3270,7 @@
9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */,
26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */,
26F4214413C6515B00E04E5E /* DynamicLoaderMacOSXKernel.cpp in Sources */,
+ 94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Tue Jul 12 17:56:10 2011
@@ -1610,8 +1610,11 @@
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;
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Jul 12 17:56:10 2011
@@ -694,6 +694,7 @@
}
}
+// 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 @@
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;
Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Tue Jul 12 17:56:10 2011
@@ -187,3 +187,33 @@
}
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;
+ }
+}
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Jul 12 17:56:10 2011
@@ -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 @@
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 @@
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 @@
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 @@
{
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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)
- {
- Error error;
- ReadPointedString(s, error);
- return error.Success();
- }
- else
+ if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
+ && val_obj_display == ValueObject::eDisplayValue)
{
- 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
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Tue Jul 12 17:56:10 2011
@@ -97,7 +97,7 @@
self.runCmd("type summary add -f \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
self.expect("frame variable strarr",
- substrs = ['arr = "Hello world!\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0"'])
+ substrs = ['arr = "Hello world!"'])
self.runCmd("type summary clear")
@@ -109,7 +109,7 @@
self.runCmd("type summary add -f \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v")
self.expect("frame variable strarr",
- substrs = ['arr = "Hello world!\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0"'])
+ substrs = ['arr = "Hello world!'])
self.expect("frame variable strptr",
substrs = ['ptr = "Hello world!"'])
Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=135007&r1=135006&r2=135007&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Tue Jul 12 17:56:10 2011
@@ -97,8 +97,13 @@
variables in your program to print out as hex, you can add
a format to the <code>int</code> type.<br></p>
- <p>This is done by typing <code>type format add -f hex
- int</code> at the LLDB command line.</p>
+ <p>This is done by typing
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> type format add -f hex int
+ </td>
+ <table>
+ at the LLDB command line.</p>
<p>The <code>-f</code> option accepts a <a
href="#formatstable">format name</a>, and a list of
@@ -124,8 +129,12 @@
untouched for other types.</p>
<p>If you simply type <br>
- <code>type format add -f hex A<br>
- type format add -f pointer C</code><br>
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> type format add -f hex A<br>
+ <b>(lldb)</b> type format add -f pointer C
+ </td>
+ <table>
<br>
values of type <code>B</code> will be shown as hex
and values of type <code>D</code> as pointers.</p>
@@ -135,8 +144,12 @@
you can use the option <code>-C no</code> to prevent
cascading, thus making the two commands required to
achieve your goal:<br>
- <code> type format add -f hex -C no A<br>
- type format add -f pointer -C no C </code></p>
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> type format add -C no -f hex A<br>
+ <b>(lldb)</b> type format add -C no -f pointer C
+ </td>
+ <table>
<p>Two additional options that you will want to look at
are <code>-p</code> and <code>-r</code>. These two
@@ -169,7 +182,11 @@
in a custom format, while leaving the others of the same
type untouched, you can simply type:<br>
<br>
- <code>frame variable counter -f hex</code></p>
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> frame variable counter -f hex
+ </td>
+ <table>
<p>This has the effect of displaying the value of <code>counter</code>
as an hexadecimal number, and will keep showing it this
@@ -365,42 +382,34 @@
<div class="post">
<h1 class="postheader">type summary</h1>
<div class="postcontent">
- <p>Type summaries enable you to add more information to
- the default viewing format for a type, or to completely
- replace it with your own display option. Unlike formats
- which only apply to basic types, summaries can be used
- on every type (basic types, classes (C++ and
- Objective-C), arrays, ...).</p>
- <p>The basic idea beneath type summaries is extracting
- information from variables and arranging it in a format
- that is suitable for display:</p>
+ <p>Type formats work by showing a different kind of display for
+ the value of a variable. However, they only work for basic types.
+ When you want to display a class or struct in a custom format, you
+ cannot do that using formats.</p>
+ <p>A different feature, type summaries, works by extracting
+ information from classes, structures, ... (<i>aggregate types</i>)
+ and arranging it in a user-defined format, as in the following example:</p>
<p> <i>before adding a summary...</i><br>
<code> <b>(lldb)</b> fr var -T one<br>
(i_am_cool) one = {<br>
- (int) integer = 3<br>
- (float) floating = 3.14159<br>
- (char) character = 'E'<br>
+ (int) integer = 3<br>
+ (float) floating = 3.14159<br>
+ (char) character = 'E'<br>
}<br>
</code> <br>
<i>after adding a summary...</i><br>
<code> <b>(lldb)</b> fr var one<br>
(i_am_cool) one = int = 3, float = 3.14159, char = 69<br>
</code> </p>
- <p>Evidently, somehow we managed to tell LLDB to grab the
- three member variables of the <code>i_am_cool</code>
- datatype, mix their values with some text, and even ask
- it to display the <code>character</code> member using a
- custom format.</p>
- <p>The way to do this is add a <i>summary string</i> to
+ <p>The way to obtain this effect is to bind a <i>summary string</i> to
the datatype using the <code>type summary add</code>
command.</p>
- <p>Its syntax is similar to <code>type format add</code>,
- but some more options are supported that will be
- described in the follow-up.</p>
- <p>The main option to <code>type summary add</code> is <code>-f</code>
- which accepts as parameter a summary string. After that,
- you can type as many type names as you want to associate
- the given summary string to them.</p>
+ <p>In the example, the command we type was:</p>
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> frame variable counter -f hex
+ </td>
+ <table>
</div>
</div>
<div class="post">
@@ -687,7 +696,13 @@
classes, look at the virtual base classes (and bases
of bases, ...)</li>
<li>If this object's type is a typedef, go through
- typedef hierarchy</li>
+ typedef hierarchy (LLDB might not be able to do this if
+ the compiler has not emitted enough information. If the
+ required information to traverse typedef hierarchies is
+ missing, type cascading will not work. The
+ <a href="http://clang.llvm.org/">clang compiler</a>,
+ part of the LLVM project, emits the correct debugging
+ information for LLDB to cascade)</li>
<li>If everything has failed, repeat the above search,
looking for regular expressions instead of exact
matches</li>
More information about the lldb-commits
mailing list