heap.py revision 9098fee45dc61264a9fe54d075751e76f7de610f
1e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton#!/usr/bin/python 2e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 3e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton#---------------------------------------------------------------------- 4e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# Be sure to add the python path that points to the LLDB shared library. 5e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# 6e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# # To use this in the embedded python interpreter using "lldb" just 7e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# import it with the full path using the "command script import" 8e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# command 9e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# (lldb) command script import /path/to/heap.py 10e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# 11e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# For the shells csh, tcsh: 12e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./heap.py ) 13e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# 14e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# For the shells sh, bash: 15e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./heap.py 16e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton#---------------------------------------------------------------------- 17e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 18e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytonimport lldb 19e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytonimport commands 20e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytonimport optparse 219666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Claytonimport os 22e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytonimport shlex 239098fee45dc61264a9fe54d075751e76f7de610fGreg Claytonimport symbolication # from lldb/examples/python/symbolication.py 24e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 259098fee45dc61264a9fe54d075751e76f7de610fGreg Claytondef load_dylib(): 269098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if lldb.target: 279098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton python_module_directory = os.path.dirname(__file__) 289098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton libheap_dylib_path = python_module_directory + '/libheap.dylib' 299098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if not os.path.exists(libheap_dylib_path): 309098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton make_command = '(cd "%s" ; make)' % python_module_directory 319098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print make_command 329098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print commands.getoutput(make_command) 339098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if os.path.exists(libheap_dylib_path): 349098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton libheap_dylib_spec = lldb.SBFileSpec(libheap_dylib_path) 359098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if lldb.target.FindModule(libheap_dylib_spec): 369098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return None # success, 'libheap.dylib' already loaded 379098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if lldb.process: 389098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton state = lldb.process.state 399098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if state == lldb.eStateStopped: 409098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton (libheap_dylib_path) 419098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton error = lldb.SBError() 429098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton image_idx = lldb.process.LoadImage(libheap_dylib_spec, error) 439098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if error.Success(): 449098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return None 459098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 469098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if error: 479098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: %s' % error 489098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 499098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: "process load \'%s\'" failed' % libheap_dylib_spec 509098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 519098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: process is not stopped' 529098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 539098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: invalid process' 549098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 559098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: file does not exist "%s"' % libheap_dylib_path 569098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 579098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 'error: invalid target' 589098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton 599098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton debugger.HandleCommand('process load "%s"' % libheap_dylib_path) 609098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton 6193e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Claytondef add_common_options(parser): 6293e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False) 6393e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False) 6493e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton parser.add_option('-m', '--memory', action='store_true', dest='memory', help='dump the memory for each matching block', default=False) 6593e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton parser.add_option('-f', '--format', type='string', dest='format', help='the format to use when dumping memory if --memory is specified', default=None) 669098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton 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) 679098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton #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) 6893e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton 699666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Claytondef heap_search(options, arg_str): 709098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton dylid_load_err = load_dylib() 719098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if dylid_load_err: 729098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print dylid_load_err 739098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton return 749666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton expr = None 75bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton arg_str_description = arg_str 7693e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton default_memory_format = "Y" # 'Y' is "bytes with ASCII" format 7793e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton #memory_chunk_size = 1 789666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if options.type == 'pointer': 79f5902cb7d5d29e72e5aba0932dda299d7aaed570Greg Clayton expr = 'find_pointer_in_heap((void *)%s)' % arg_str 80bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton arg_str_description = 'malloc block containing pointer %s' % arg_str 8193e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton default_memory_format = "A" # 'A' is "address" format 8293e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton #memory_chunk_size = lldb.process.GetAddressByteSize() 839666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton elif options.type == 'cstr': 849666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton expr = 'find_cstring_in_heap("%s")' % arg_str 85bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton arg_str_description = 'malloc block containing "%s"' % arg_str 86bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton elif options.type == 'addr': 87f5902cb7d5d29e72e5aba0932dda299d7aaed570Greg Clayton expr = 'find_block_for_address((void *)%s)' % arg_str 88bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton arg_str_description = 'malloc block for %s' % arg_str 899666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton else: 909666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type 919666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton return 929666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 939666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton expr_sbvalue = lldb.frame.EvaluateExpression (expr) 949666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if expr_sbvalue.error.Success(): 959666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if expr_sbvalue.unsigned: 969666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton match_value = lldb.value(expr_sbvalue) 979666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton i = 0 989666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton while 1: 999666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton match_entry = match_value[i]; i += 1 1009666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton malloc_addr = match_entry.addr.sbvalue.unsigned 1019666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if malloc_addr == 0: 1029666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton break 1039666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton malloc_size = int(match_entry.size) 1049666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton offset = int(match_entry.offset) 1059666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget) 1069666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton # If the type is still 'void *' then we weren't able to figure 1079666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton # out a dynamic type for the malloc_addr 1089666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton type_name = dynamic_value.type.name 109bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description = '[%u] %s: addr = 0x%x' % (i, arg_str_description, malloc_addr) 110bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if offset != 0: 111bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description += ' + %u' % (offset) 112bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description += ', size = %u' % (malloc_size) 1139666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if type_name == 'void *': 1149666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if options.type == 'pointer' and malloc_size == 4096: 1159666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton error = lldb.SBError() 1169666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error)) 1179666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if data == '\xa1\xa1\xa1\xa1AUTORELEASE!': 118bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description += ', type = (AUTORELEASE!)' 11993e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton print description 120bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton else: 121bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description += ', type = %s' % (type_name) 122bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton derefed_dynamic_value = dynamic_value.deref 123bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton ivar_member = None 124bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if derefed_dynamic_value: 125bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton derefed_dynamic_type = derefed_dynamic_value.type 126bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member = derefed_dynamic_type.GetFieldAtIndex(0) 127bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton search_bases = False 128bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if member: 129bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if member.GetOffsetInBytes() <= offset: 130bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton for field_idx in range (derefed_dynamic_type.GetNumberOfFields()): 131bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member = derefed_dynamic_type.GetFieldAtIndex(field_idx) 132bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member_byte_offset = member.GetOffsetInBytes() 133bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if member_byte_offset == offset: 134bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton ivar_member = member 135bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton break 136bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton else: 137bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton search_bases = True 1389666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton else: 1399666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton search_bases = True 140bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 141bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if not ivar_member and search_bases: 142bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton for field_idx in range (derefed_dynamic_type.GetNumberOfDirectBaseClasses()): 143bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member = derefed_dynamic_type.GetDirectBaseClassAtIndex(field_idx) 1449666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton member_byte_offset = member.GetOffsetInBytes() 1459666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if member_byte_offset == offset: 1469666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton ivar_member = member 1479666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton break 148bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if not ivar_member: 149bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton for field_idx in range (derefed_dynamic_type.GetNumberOfVirtualBaseClasses()): 150bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member = derefed_dynamic_type.GetVirtualBaseClassAtIndex(field_idx) 151bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton member_byte_offset = member.GetOffsetInBytes() 152bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if member_byte_offset == offset: 153bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton ivar_member = member 154bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton break 1559666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if ivar_member: 156bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description +=', ivar = %s' % (ivar_member.name) 157bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 158bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print description 159bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if derefed_dynamic_value: 160bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print derefed_dynamic_value 161bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if options.print_object_description: 162bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton desc = dynamic_value.GetObjectDescription() 163bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if desc: 164bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc) 16593e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton if options.memory: 16693e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton memory_format = options.format 16793e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton if not memory_format: 16893e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton memory_format = default_memory_format 16993e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton cmd_result = lldb.SBCommandReturnObject() 17093e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton #count = malloc_size / memory_chunk_size 17193e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton memory_command = "memory read -f %s 0x%x 0x%x" % (memory_format, malloc_addr, malloc_addr + malloc_size) 17293e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result) 17393e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton print cmd_result.GetOutput() 1749098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if options.stack: 1759098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton symbolicator = symbolication.Symbolicator() 1769098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton symbolicator.target = lldb.target 1779098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton expr_str = "g_stack_frames_count = sizeof(g_stack_frames)/sizeof(uint64_t); (int)__mach_stack_logging_get_frames((unsigned)mach_task_self(), 0x%xull, g_stack_frames, g_stack_frames_count, &g_stack_frames_count)" % (malloc_addr) 1789098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton #print expr_str 1799098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton expr = lldb.frame.EvaluateExpression (expr_str); 1809098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton expr_error = expr.GetError() 1819098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if expr_error.Success(): 1829098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton err = expr.unsigned 1839098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if err: 1849098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print 'error: __mach_stack_logging_get_frames() returned error %i' % (err) 1859098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 1869098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton count_expr = lldb.frame.EvaluateExpression ("g_stack_frames_count") 1879098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton count = count_expr.unsigned 1889098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton #print 'g_stack_frames_count is %u' % (count) 1899098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if count > 0: 1909098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frame_idx = 0 1919098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frames_expr = lldb.value(lldb.frame.EvaluateExpression ("g_stack_frames")) 1929098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton done = False 1939098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton for stack_frame_idx in range(count): 1949098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if not done: 1959098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frame_load_addr = int(frames_expr[stack_frame_idx]) 1969098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if frame_load_addr >= 0x1000: 1979098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frames = symbolicator.symbolicate(frame_load_addr) 1989098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton if frames: 1999098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton for frame in frames: 2009098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print '[%3u] %s' % (frame_idx, frame) 2019098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frame_idx += 1 2029098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 2039098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print '[%3u] 0x%x' % (frame_idx, frame_load_addr) 2049098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton frame_idx += 1 2059098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 2069098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton done = True 2079098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton else: 2089098fee45dc61264a9fe54d075751e76f7de610fGreg Clayton print 'error: %s' % (expr_error) 2099666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton else: 2109666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton print '%s %s was not found in any malloc blocks' % (options.type, arg_str) 2119666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton else: 212bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print expr_sbvalue.error 213bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print 2149666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 215bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef ptr_refs(debugger, command, result, dict): 216e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton command_args = shlex.split(command) 217bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton usage = "usage: %prog [options] <PTR> [PTR ...]" 2189666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton description='''Searches the heap for pointer references on darwin user space programs. 2199666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 2209666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton Any matches that were found will dump the malloc blocks that contain the pointers 2219666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton and might be able to print what kind of objects the pointers are contained in using 222bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton dynamic type information in the program.''' 223bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton parser = optparse.OptionParser(description=description, prog='ptr_refs',usage=usage) 22493e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton add_common_options(parser) 225e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton try: 226e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton (options, args) = parser.parse_args(command_args) 227e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton except: 228e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton return 2299666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 2309666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton options.type = 'pointer' 231e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 232e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton if args: 233e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 234e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton for data in args: 2359666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton heap_search (options, data) 236e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton else: 2379666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton print 'error: no pointer arguments were given' 2389666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 239bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef cstr_refs(debugger, command, result, dict): 2409666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton command_args = shlex.split(command) 241bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton usage = "usage: %prog [options] <CSTR> [CSTR ...]" 2429666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton description='''Searches the heap for C string references on darwin user space programs. 2439666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 2449666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton Any matches that were found will dump the malloc blocks that contain the C strings 2459666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton and might be able to print what kind of objects the pointers are contained in using 246bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton dynamic type information in the program.''' 247bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage) 24893e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton add_common_options(parser) 2499666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton try: 2509666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton (options, args) = parser.parse_args(command_args) 2519666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton except: 2529666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton return 2539666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 2549666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton options.type = 'cstr' 255e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 2569666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton if args: 2579666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton 2589666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton for data in args: 2599666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton heap_search (options, data) 2609666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton else: 2619666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton print 'error: no c string arguments were given to search for' 262e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 263bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef malloc_info(debugger, command, result, dict): 264bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton command_args = shlex.split(command) 265bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton usage = "usage: %prog [options] <ADDR> [ADDR ...]" 266bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton description='''Searches the heap a malloc block that contains the addresses specified as arguments. 267bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 268bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton Any matches that were found will dump the malloc blocks that match or contain 269bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton the specified address. The matching blocks might be able to show what kind 270bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton of objects they are using dynamic type information in the program.''' 271bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage) 27293e5ba5ec34531a68b2d3bc82c3bcb2aa8d22032Greg Clayton add_common_options(parser) 273bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton try: 274bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton (options, args) = parser.parse_args(command_args) 275bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton except: 276bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton return 277bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 278bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton options.type = 'addr' 279bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 280bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton if args: 281bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 282bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton for data in args: 283bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton heap_search (options, data) 284bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton else: 285bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print 'error: no c string arguments were given to search for' 286bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton 287e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytondef __lldb_init_module (debugger, dict): 288e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton # This initializer is being run from LLDB in the embedded command interpreter 289e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton # Add any commands contained in this module to LLDB 290bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton debugger.HandleCommand('command script add -f heap.ptr_refs ptr_refs') 291bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton debugger.HandleCommand('command script add -f heap.cstr_refs cstr_refs') 292bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton debugger.HandleCommand('command script add -f heap.malloc_info malloc_info') 293bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton print '"ptr_refs", "cstr_refs", and "malloc_info" commands have been installed, use the "--help" options on these commands for detailed help.' 294e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 295e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 296e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 297e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton 298