Don't allow an extra entry to slip into the heap results and also add a better output format

llvm-svn: 163675
This commit is contained in:
Greg Clayton 2012-09-12 02:02:32 +00:00
parent 66a34a6a45
commit a3606adf90
2 changed files with 42 additions and 15 deletions
lldb/examples/darwin/heap_find

View File

@ -124,6 +124,8 @@ def add_common_options(parser):
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
parser.add_option('-t', '--type', action='store_true', dest='print_type', help='print the full value of the type for each matching malloc block', default=False)
parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False)
parser.add_option('-z', '--size', action='store_true', dest='show_size', help='print the allocation size in bytes', default=False)
parser.add_option('-r', '--range', action='store_true', dest='show_range', help='print the allocation address range instead of just the allocation base address', default=False)
parser.add_option('-m', '--memory', action='store_true', dest='memory', help='dump the memory for each matching block', default=False)
parser.add_option('-f', '--format', type='string', dest='format', help='the format to use when dumping memory if --memory is specified', default=None)
parser.add_option('-I', '--omit-ivar-regex', type='string', action='callback', callback=append_regex_callback, dest='ivar_regex_blacklist', default=[], help='specify one or more regular expressions used to backlist any matches that are in ivars')
@ -212,24 +214,45 @@ def display_match_results (result, options, arg_str_description, expr_sbvalue, p
else:
match_addr = malloc_addr + offset
dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
description = '[%u] %s: addr = 0x%x' % (match_idx, arg_str_description, malloc_addr)
if offset != 0:
description += ' + %u' % (offset)
description += ', size = %u' % (malloc_size)
description = '%#x: ' % (match_addr)
if options.show_size:
description += '<%5u> ' % (malloc_size)
if options.show_range:
if offset > 0:
description += '[%#x - %#x) + %-6u ' % (malloc_addr, malloc_addr + malloc_size, offset)
else:
description += '[%#x - %#x)' % (malloc_addr, malloc_addr + malloc_size)
else:
if options.type != 'isa':
description += '%#x + %-6u ' % (malloc_addr, offset)
derefed_dynamic_value = None
if dynamic_value.type.name == 'void *':
if options.type == 'pointer' and malloc_size == 4096:
error = lldb.SBError()
data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
description += ', type = (AUTORELEASE!)'
ptr_size = lldb.target.addr_size
thread = lldb.process.ReadUnsignedFromMemory (malloc_addr + 16 + ptr_size, ptr_size, error)
# 4 bytes 0xa1a1a1a1
# 12 bytes 'AUTORELEASE!'
# ptr bytes autorelease insertion point
# ptr bytes pthread_t
# ptr bytes next colder page
# ptr bytes next hotter page
# 4 bytes this page's depth in the list
# 4 bytes high-water mark
description += 'AUTORELEASE! for pthread_t %#x' % (thread)
else:
description += 'malloc(%u)' % (malloc_size)
else:
description += 'malloc(%u)' % (malloc_size)
else:
derefed_dynamic_value = dynamic_value.deref
if derefed_dynamic_value:
derefed_dynamic_type = derefed_dynamic_value.type
derefed_dynamic_type_size = derefed_dynamic_type.size
derefed_dynamic_type_name = derefed_dynamic_type.name
description += ', type = %s <%u>' % (derefed_dynamic_type_name, derefed_dynamic_type_size)
description += derefed_dynamic_type_name
if offset < derefed_dynamic_type_size:
member_list = list();
get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
@ -246,7 +269,12 @@ def display_match_results (result, options, arg_str_description, expr_sbvalue, p
for ivar_regex in options.ivar_regex_blacklist:
if ivar_regex.match(member_path):
print_entry = False
description += ', ivar = %s' % (member_path)
description += '.%s' % (member_path)
else:
description += '%u bytes after %s' % (offset - derefed_dynamic_type_size, derefed_dynamic_type_name)
else:
# strip the "*" from the end of the name since we were unable to dereference this
description += dynamic_value.type.name[0:-1]
if print_entry:
match_idx += 1
result_output = ''
@ -257,7 +285,7 @@ def display_match_results (result, options, arg_str_description, expr_sbvalue, p
if options.print_object_description and dynamic_value:
desc = dynamic_value.GetObjectDescription()
if desc:
result_output += ', po=%s' % (desc)
result_output += '\n%s' % (desc)
if result_output:
result.AppendMessage(result_output)
if options.memory:
@ -471,7 +499,7 @@ def objc_refs(debugger, command, result, dict):
isa = expr_sbvalue.unsigned
if isa:
options.type = 'isa'
result.AppendMessage('Searching for all instances of %s (isa=0x%x)' % (class_name, isa))
result.AppendMessage('Searching for all instances of classes or subclasses of %s (isa=0x%x)' % (class_name, isa))
heap_search (result, options, '0x%x' % isa)
else:
result.AppendMessage('error: Can\'t find isa for an ObjC class named "%s"' % (class_name))

View File

@ -266,7 +266,7 @@ public:
// In not empty, terminate and return the result
malloc_match terminator_entry = { NULL, 0, 0 };
// We always leave room for an empty entry at the end
m_entries[m_size + 1] = terminator_entry;
m_entries[m_size] = terminator_entry;
return m_entries;
}
@ -316,10 +316,10 @@ public:
if (empty())
return NULL;
// In not empty, terminate and return the result
m_entries[m_size + 1].address = NULL;
m_entries[m_size + 1].argument = 0;
m_entries[m_size + 1].type_flags = 0;
m_entries[m_size + 1].num_frames = 0;
m_entries[m_size].address = NULL;
m_entries[m_size].argument = 0;
m_entries[m_size].type_flags = 0;
m_entries[m_size].num_frames = 0;
return m_entries;
}
@ -419,7 +419,6 @@ private:
//----------------------------------------------------------------------
// Local global variables
//----------------------------------------------------------------------
//std::vector<malloc_match> g_matches;
MatchResults g_matches;
MallocStackLoggingEntries g_malloc_stack_history;
ObjCClasses g_objc_classes;