[Lldb-commits] [lldb] r160083 - in /lldb/trunk/examples/darwin/heap_find: heap.py heap/heap_find.cpp
Greg Clayton
gclayton at apple.com
Wed Jul 11 15:13:18 PDT 2012
Author: gclayton
Date: Wed Jul 11 17:13:18 2012
New Revision: 160083
URL: http://llvm.org/viewvc/llvm-project?rev=160083&view=rev
Log:
Added the ability to search through sections for pointer data.
Modified:
lldb/trunk/examples/darwin/heap_find/heap.py
lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp
Modified: lldb/trunk/examples/darwin/heap_find/heap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/darwin/heap_find/heap.py?rev=160083&r1=160082&r2=160083&view=diff
==============================================================================
--- lldb/trunk/examples/darwin/heap_find/heap.py (original)
+++ lldb/trunk/examples/darwin/heap_find/heap.py Wed Jul 11 17:13:18 2012
@@ -13,6 +13,7 @@
import optparse
import os
import os.path
+import re
import shlex
import string
import tempfile
@@ -112,14 +113,24 @@
member_list.append(member)
get_member_types_for_offset (member.type, offset - member_byte_offset, member_list)
return
+
+def append_regex_callback(option, opt, value, parser):
+ try:
+ ivar_regex = re.compile(value)
+ parser.values.ivar_regex_blacklist.append(ivar_regex)
+ except:
+ print 'error: an exception was thrown when compiling the ivar regular expression for "%s"' % value
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('-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')
parser.add_option('-s', '--stack', action='store_true', dest='stack', help='gets the stack that allocated each malloc block if MallocStackLogging is enabled', default=False)
parser.add_option('-S', '--stack-history', action='store_true', dest='stack_history', help='gets the stack history for all allocations whose start address matches each malloc block if MallocStackLogging is enabled', default=False)
+ parser.add_option('-M', '--max-matches', type='int', dest='max_matches', help='the maximum number of matches to print', default=256)
def dump_stack_history_entry(stack_history_entry, idx):
address = int(stack_history_entry.address)
@@ -172,43 +183,21 @@
dump_stack_history_entry(stack_history_entry, idx)
idx = idx + 1
stack_history_entry = expr_value[idx]
- else:
- print 'error: expression returned => %s' % (expr_sbvalue)
else:
print 'error: expression failed "%s" => %s' % (expr, expr_sbvalue.error)
-
-def heap_search(options, arg_str):
- dylid_load_err = load_dylib()
- if dylid_load_err:
- print dylid_load_err
- return
- expr = None
- arg_str_description = arg_str
- default_memory_format = "Y" # 'Y' is "bytes with ASCII" format
- #memory_chunk_size = 1
- if options.type == 'pointer':
- expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
- arg_str_description = 'malloc block containing pointer %s' % arg_str
- default_memory_format = "A" # 'A' is "address" format
- #memory_chunk_size = lldb.process.GetAddressByteSize()
- elif options.type == 'cstr':
- expr = 'find_cstring_in_heap("%s")' % arg_str
- arg_str_description = 'malloc block containing "%s"' % arg_str
- elif options.type == 'addr':
- expr = 'find_block_for_address((void *)%s)' % arg_str
- arg_str_description = 'malloc block for %s' % arg_str
- else:
- print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
- return
-
- expr_sbvalue = lldb.frame.EvaluateExpression (expr)
+
+def display_match_results (options, arg_str_description, expr_sbvalue, print_no_matches = True):
if expr_sbvalue.error.Success():
if expr_sbvalue.unsigned:
match_value = lldb.value(expr_sbvalue)
i = 0
while 1:
+ print_entry = True
match_entry = match_value[i]; i += 1
+ if i >= options.max_matches:
+ print 'error: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches)
+ break
malloc_addr = match_entry.addr.sbvalue.unsigned
if malloc_addr == 0:
break
@@ -220,13 +209,13 @@
if offset != 0:
description += ' + %u' % (offset)
description += ', size = %u' % (malloc_size)
+ 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!)'
- print description
else:
derefed_dynamic_value = dynamic_value.deref
if derefed_dynamic_value:
@@ -246,32 +235,61 @@
member_path += '.'
member_path += member_name
if member_path:
+ if options.ivar_regex_blacklist:
+ for ivar_regex in options.ivar_regex_blacklist:
+ if ivar_regex.match(member_path):
+ print_entry = False
description += ', ivar = %s' % (member_path)
- print description
- if derefed_dynamic_value:
- print derefed_dynamic_value
- if options.print_object_description:
- desc = dynamic_value.GetObjectDescription()
- if desc:
- print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
- if options.memory:
- memory_format = options.format
- if not memory_format:
- memory_format = default_memory_format
- cmd_result = lldb.SBCommandReturnObject()
- #count = malloc_size / memory_chunk_size
- memory_command = "memory read -f %s 0x%x 0x%x" % (memory_format, malloc_addr, malloc_addr + malloc_size)
- lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
- print cmd_result.GetOutput()
- if options.stack_history:
- dump_stack_history_entries(malloc_addr, 1)
- elif options.stack:
- dump_stack_history_entries(malloc_addr, 0)
- else:
- print '%s %s was not found in any malloc blocks' % (options.type, arg_str)
+ if print_entry:
+ if description:
+ print description
+ if options.print_type and derefed_dynamic_value:
+ print derefed_dynamic_value
+ if options.print_object_description and dynamic_value:
+ desc = dynamic_value.GetObjectDescription()
+ if desc:
+ print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
+ if options.memory:
+ cmd_result = lldb.SBCommandReturnObject()
+ memory_command = "memory read -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
+ lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
+ print cmd_result.GetOutput()
+ if options.stack_history:
+ dump_stack_history_entries(malloc_addr, 1)
+ elif options.stack:
+ dump_stack_history_entries(malloc_addr, 0)
+ return i
+ elif print_no_matches:
+ print 'no matches found for %s' % (arg_str_description)
else:
print expr_sbvalue.error
- print
+ return 0
+
+def heap_search(options, arg_str):
+ dylid_load_err = load_dylib()
+ if dylid_load_err:
+ print dylid_load_err
+ return
+ expr = None
+ arg_str_description = arg_str
+ if options.format == None:
+ options.format = "Y" # 'Y' is "bytes with ASCII" format
+ if options.type == 'pointer':
+ expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
+ arg_str_description = 'malloc block containing pointer %s' % arg_str
+ if options.format == None:
+ options.format = "A" # 'A' is "address" format
+ elif options.type == 'cstr':
+ expr = 'find_cstring_in_heap("%s")' % arg_str
+ arg_str_description = 'malloc block containing "%s"' % arg_str
+ elif options.type == 'addr':
+ expr = 'find_block_for_address((void *)%s)' % arg_str
+ arg_str_description = 'malloc block for %s' % arg_str
+ else:
+ print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
+ return
+
+ display_match_results (options, arg_str_description, lldb.frame.EvaluateExpression (expr))
def ptr_refs(debugger, command, result, dict):
command_args = shlex.split(command)
@@ -366,6 +384,52 @@
else:
print 'error: no address expressions were specified'
+def section_ptr_refs(debugger, command, result, dict):
+ command_args = shlex.split(command)
+ usage = "usage: %prog [options] <EXPR> [EXPR ...]"
+ description='''Searches section contents for pointer values in darwin user space programs.'''
+ parser = optparse.OptionParser(description=description, prog='section_ptr_refs',usage=usage)
+ add_common_options(parser)
+ parser.add_option('--section', action='append', type='string', dest='section_names', help='section name to search', default=list())
+ try:
+ (options, args) = parser.parse_args(command_args)
+ except:
+ return
+
+ options.type = 'pointer'
+
+ sections = list()
+ section_modules = list()
+ if not options.section_names:
+ print 'error: at least one section must be specified with the --section option'
+ return
+
+ for module in lldb.target.modules:
+ for section_name in options.section_names:
+ section = module.section[section_name]
+ if section:
+ sections.append (section)
+ section_modules.append (module)
+ if sections:
+ dylid_load_err = load_dylib()
+ if dylid_load_err:
+ print dylid_load_err
+ return
+ for expr_str in args:
+ for (idx, section) in enumerate(sections):
+ expr = 'find_pointer_in_memory(0x%xllu, %ullu, (void *)%s)' % (section.addr.load_addr, section.size, expr_str)
+ arg_str_description = 'section %s.%s containing "%s"' % (section_modules[idx].file.fullpath, section.name, expr_str)
+ num_matches = display_match_results (options, arg_str_description, lldb.frame.EvaluateExpression (expr), False)
+ if num_matches:
+ if num_matches < options.max_matches:
+ options.max_matches = options.max_matches - num_matches
+ else:
+ options.max_matches = 0
+ if options.max_matches == 0:
+ return
+ else:
+ print 'error: no sections were found that match any of %s' % (', '.join(options.section_names))
+
if __name__ == '__main__':
lldb.debugger = lldb.SBDebugger.Create()
@@ -375,7 +439,8 @@
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.cstr_refs cstr_refs')
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_info malloc_info')
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_history malloc_history')
-print '"ptr_refs", "cstr_refs", "malloc_info", and "malloc_history" commands have been installed, use the "--help" options on these commands for detailed help.'
+lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.section_ptr_refs section_ptr_refs')
+print '"ptr_refs", "cstr_refs", "malloc_info", "malloc_history" and "section_ptr_refs" commands have been installed, use the "--help" options on these commands for detailed help.'
Modified: lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp?rev=160083&r1=160082&r2=160083&view=diff
==============================================================================
--- lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp (original)
+++ lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp Wed Jul 11 17:13:18 2012
@@ -416,6 +416,33 @@
return g_matches.data();
}
+//----------------------------------------------------------------------
+// find_pointer_in_memory
+//
+// Finds a pointer value inside one or more currently valid malloc
+// blocks.
+//----------------------------------------------------------------------
+malloc_match *
+find_pointer_in_memory (uint64_t memory_addr, uint64_t memory_size, const void * addr)
+{
+ g_matches.clear();
+ // Setup "info" to look for a malloc block that contains data
+ // that is the a pointer
+ range_contains_data_callback_info_t data_info;
+ data_info.type = eDataTypeContainsData; // Check each block for data
+ g_lookup_addr = addr;
+ data_info.data.buffer = (uint8_t *)&addr; // What data? The pointer value passed in
+ data_info.data.size = sizeof(addr); // How many bytes? The byte size of a pointer
+ data_info.data.align = sizeof(addr); // Align to a pointer byte size
+ data_info.match_count = 0; // Initialize the match count to zero
+ data_info.done = false; // Set done to false so searching doesn't stop
+ range_info_callback (mach_task_self(), &data_info, stack_logging_type_generic, memory_addr, memory_size);
+ if (g_matches.empty())
+ return NULL;
+ malloc_match match = { NULL, 0, 0 };
+ g_matches.push_back(match);
+ return g_matches.data();
+}
//----------------------------------------------------------------------
// find_cstring_in_heap
More information about the lldb-commits
mailing list