blob: e5405da201b34018ac9b257e145593ad29b74ce3 [file] [log] [blame]
Greg Claytone93e24f2012-04-11 16:27:06 +00001#!/usr/bin/python
2
3#----------------------------------------------------------------------
4# Be sure to add the python path that points to the LLDB shared library.
5#
6# # To use this in the embedded python interpreter using "lldb" just
7# import it with the full path using the "command script import"
8# command
9# (lldb) command script import /path/to/heap.py
10#
11# For the shells csh, tcsh:
12# ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./heap.py )
13#
14# For the shells sh, bash:
15# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./heap.py
16#----------------------------------------------------------------------
17
18import lldb
19import commands
20import optparse
21import shlex
22
23def heap_search(debugger, command, result, dict):
24 command_args = shlex.split(command)
25 usage = "usage: %prog [options] <PATH> [PATH ...]"
26 description='''This command lets you run the /bin/ls command from within lldb as a quick and easy example.'''
27 parser = optparse.OptionParser(description=description, prog='heap_search',usage=usage)
28 parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
29 parser.add_option('-t', '--type', type='string', dest='type', help='the type of data to search for (defaults to "pointer")', default='pointer')
30 parser.add_option('-o', '--po', action='store_true', dest='po', default='print the object descriptions for any matches')
31 try:
32 (options, args) = parser.parse_args(command_args)
33 except:
34 return
35
36 if args:
37
38 for data in args:
39 if options.type == 'pointer':
40 ptr = int(data, 0)
41 expr = 'find_pointer_in_heap(0x%x)' % ptr
42 #print 'expr: %s' % expr
43 expr_sbvalue = lldb.frame.EvaluateExpression (expr)
44 if expr_sbvalue.error.Success():
45 if expr_sbvalue.unsigned:
46 match_value = lldb.value(expr_sbvalue)
47 i = 0
48 while 1:
49 match_entry = match_value[i]; i += 1
50 malloc_addr = int(match_entry.addr)
51 if malloc_addr == 0:
52 break
53 malloc_size = int(match_entry.size)
54 offset = int(match_entry.offset)
55 dynamic_value = match_entry.addr.sbvalue.dynamic
56 # If the type is still 'void *' then we weren't able to figure
57 # out a dynamic type for the malloc_addr
58 type_name = dynamic_value.type.name
59 if type_name == 'void *':
60 if malloc_size == 4096:
61 error = lldb.SBError()
62 data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
63 if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
64 print 'found %s 0x%x in (autorelease object pool) 0x%x, malloc_size = %u, offset = %u' % (options.type, ptr, malloc_addr, malloc_size, offset)
65 continue
66 print 'found %s 0x%x in malloc block 0x%x, malloc_size = %u, offset = %u' % (options.type, ptr, malloc_addr, malloc_size, offset)
67 else:
68 print 'found %s 0x%x in (%s) 0x%x, malloc_size = %u, offset = %u' % (options.type, ptr, type_name, malloc_addr, malloc_size, offset)
69 if options.po:
70 desc = dynamic_value.GetObjectDescription()
71 if desc:
72 print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
73 else:
74 print '%s 0x%x was not found in any malloc blocks' % (options.type, ptr)
75 else:
76 print expr_sbvalue.error
77 elif options.type == 'cstring':
78 expr = 'find_cstring_in_heap("%s")' % data
79 #print 'expr: %s' % expr
80 expr_sbvalue = lldb.frame.EvaluateExpression (expr)
81 if expr_sbvalue.error.Success():
82 if expr_sbvalue.unsigned:
83 match_value = lldb.value(expr_sbvalue)
84 print match_value
85 i = 0
86 while 1:
87 match_entry = match_value[i]; i += 1
88 malloc_addr = int(match_entry.addr)
89 if malloc_addr == 0:
90 break
91 malloc_size = int(match_entry.size)
92 offset = int(match_entry.offset)
93 dynamic_value = match_entry.addr.sbvalue.dynamic
94 # If the type is still 'void *' then we weren't able to figure
95 # out a dynamic type for the malloc_addr
96 type_name = dynamic_value.type.name
97 if type_name == 'void *':
98 print 'found %s "%s" in malloc block 0x%x, malloc_size = %u, offset = %u' % (options.type, data, malloc_addr, malloc_size, offset)
99 else:
100 print 'found %s "%s" in (%s) 0x%x, malloc_size = %u, offset = %u' % (options.type, data, type_name, malloc_addr, malloc_size, offset)
101 if options.po:
102 desc = dynamic_value.GetObjectDescription()
103 if desc:
104 print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
105 else:
106 print '%s "%s" was not found in any malloc blocks' % (options.type, data)
107 else:
108 print expr_sbvalue.error
109
110 else:
111 print 'error: invalid type "%s"\nvalid values are "pointer", "cstring"' % options.type
112 sys.exit(1)
113 else:
114 print 'error: no arguments were given'
115
116if __name__ == '__main__':
117 # This script is being run from the command line, create a debugger in case we are
118 # going to use any debugger functions in our function.
119 lldb.debugger = lldb.SBDebugger.Create()
120 ls (sys.argv)
121
122def __lldb_init_module (debugger, dict):
123 # This initializer is being run from LLDB in the embedded command interpreter
124 # Add any commands contained in this module to LLDB
125 debugger.HandleCommand('process load /Volumes/work/gclayton/Documents/src/lldb/examples/darwin/heap_find/libheap.dylib')
126 debugger.HandleCommand('command script add -f heap.heap_search heap_search')
127 print '"heap_search" command installed, type "heap_search --help" for detailed help'
128
129
130
131