blob: c829cc8f00124051c7d7b0b80fccf47757b8976a [file] [log] [blame]
Greg Clayton804de012012-04-11 16:27:06 +00001#!/usr/bin/python
2
3#----------------------------------------------------------------------
Greg Claytond712ef02012-04-25 18:40:20 +00004# This module is designed to live inside the "lldb" python package
5# in the "lldb.macosx" package. To use this in the embedded python
6# interpreter using "lldb" just import it:
Greg Clayton804de012012-04-11 16:27:06 +00007#
Greg Claytond712ef02012-04-25 18:40:20 +00008# (lldb) script import lldb.macosx.heap
Greg Clayton804de012012-04-11 16:27:06 +00009#----------------------------------------------------------------------
10
11import lldb
12import commands
13import optparse
Greg Clayton7fb671b2012-04-11 18:30:53 +000014import os
Greg Claytond712ef02012-04-25 18:40:20 +000015import os.path
Greg Claytone04cfd22012-07-11 22:13:18 +000016import re
Greg Clayton804de012012-04-11 16:27:06 +000017import shlex
Greg Claytond712ef02012-04-25 18:40:20 +000018import string
19import tempfile
Greg Claytoned3eee62012-04-25 01:49:50 +000020import lldb.utils.symbolication
Greg Clayton804de012012-04-11 16:27:06 +000021
Greg Claytond712ef02012-04-25 18:40:20 +000022g_libheap_dylib_dir = None
23g_libheap_dylib_dict = dict()
Greg Clayton341039f2012-05-11 02:42:36 +000024g_verbose = False
Greg Claytond712ef02012-04-25 18:40:20 +000025
Greg Claytonb403a152012-04-21 00:11:26 +000026def load_dylib():
27 if lldb.target:
Greg Claytond712ef02012-04-25 18:40:20 +000028 global g_libheap_dylib_dir
29 global g_libheap_dylib_dict
30 triple = lldb.target.triple
Greg Clayton4f76fef2012-04-25 21:23:07 +000031 if triple in g_libheap_dylib_dict:
32 libheap_dylib_path = g_libheap_dylib_dict[triple]
33 else:
Greg Claytond712ef02012-04-25 18:40:20 +000034 if not g_libheap_dylib_dir:
Greg Clayton4f76fef2012-04-25 21:23:07 +000035 g_libheap_dylib_dir = tempfile.gettempdir() + '/lldb-dylibs'
36 triple_dir = g_libheap_dylib_dir + '/' + triple + '/' + __name__
Greg Claytond712ef02012-04-25 18:40:20 +000037 if not os.path.exists(triple_dir):
Greg Clayton4f76fef2012-04-25 21:23:07 +000038 os.makedirs(triple_dir)
Greg Claytond712ef02012-04-25 18:40:20 +000039 libheap_dylib_path = triple_dir + '/libheap.dylib'
40 g_libheap_dylib_dict[triple] = libheap_dylib_path
Greg Clayton4f76fef2012-04-25 21:23:07 +000041 heap_code_directory = os.path.dirname(__file__) + '/heap'
42 heap_source_file = heap_code_directory + '/heap_find.cpp'
43 # Check if the dylib doesn't exist, or if "heap_find.cpp" is newer than the dylib
44 if not os.path.exists(libheap_dylib_path) or os.stat(heap_source_file).st_mtime > os.stat(libheap_dylib_path).st_mtime:
45 # Remake the dylib
Greg Claytond712ef02012-04-25 18:40:20 +000046 make_command = '(cd "%s" ; make EXE="%s" ARCH=%s)' % (heap_code_directory, libheap_dylib_path, string.split(triple, '-')[0])
Greg Clayton4f76fef2012-04-25 21:23:07 +000047 # print make_command
Greg Clayton89d4f332012-06-27 19:57:59 +000048 (make_exit_status, make_output) = commands.getstatusoutput(make_command)
49 if make_exit_status != 0:
50 print make_output
Greg Claytonb403a152012-04-21 00:11:26 +000051 if os.path.exists(libheap_dylib_path):
52 libheap_dylib_spec = lldb.SBFileSpec(libheap_dylib_path)
53 if lldb.target.FindModule(libheap_dylib_spec):
54 return None # success, 'libheap.dylib' already loaded
55 if lldb.process:
56 state = lldb.process.state
57 if state == lldb.eStateStopped:
58 (libheap_dylib_path)
59 error = lldb.SBError()
60 image_idx = lldb.process.LoadImage(libheap_dylib_spec, error)
61 if error.Success():
62 return None
63 else:
64 if error:
65 return 'error: %s' % error
66 else:
67 return 'error: "process load \'%s\'" failed' % libheap_dylib_spec
68 else:
69 return 'error: process is not stopped'
70 else:
71 return 'error: invalid process'
72 else:
73 return 'error: file does not exist "%s"' % libheap_dylib_path
74 else:
75 return 'error: invalid target'
76
77 debugger.HandleCommand('process load "%s"' % libheap_dylib_path)
Greg Clayton341039f2012-05-11 02:42:36 +000078 if lldb.target.FindModule(libheap_dylib_spec):
79 return None # success, 'libheap.dylib' already loaded
80 return 'error: failed to load "%s"' % libheap_dylib_path
Greg Clayton94073022012-07-07 01:22:45 +000081
82def get_member_types_for_offset(value_type, offset, member_list):
83 member = value_type.GetFieldAtIndex(0)
84 search_bases = False
85 if member:
86 if member.GetOffsetInBytes() <= offset:
87 for field_idx in range (value_type.GetNumberOfFields()):
88 member = value_type.GetFieldAtIndex(field_idx)
89 member_byte_offset = member.GetOffsetInBytes()
90 member_end_byte_offset = member_byte_offset + member.type.size
91 if member_byte_offset <= offset and offset < member_end_byte_offset:
92 member_list.append(member)
93 get_member_types_for_offset (member.type, offset - member_byte_offset, member_list)
94 return
95 else:
96 search_bases = True
97 else:
98 search_bases = True
99 if search_bases:
100 for field_idx in range (value_type.GetNumberOfDirectBaseClasses()):
101 member = value_type.GetDirectBaseClassAtIndex(field_idx)
102 member_byte_offset = member.GetOffsetInBytes()
103 member_end_byte_offset = member_byte_offset + member.type.size
104 if member_byte_offset <= offset and offset < member_end_byte_offset:
105 member_list.append(member)
106 get_member_types_for_offset (member.type, offset - member_byte_offset, member_list)
107 return
108 for field_idx in range (value_type.GetNumberOfVirtualBaseClasses()):
109 member = value_type.GetVirtualBaseClassAtIndex(field_idx)
110 member_byte_offset = member.GetOffsetInBytes()
111 member_end_byte_offset = member_byte_offset + member.type.size
112 if member_byte_offset <= offset and offset < member_end_byte_offset:
113 member_list.append(member)
114 get_member_types_for_offset (member.type, offset - member_byte_offset, member_list)
115 return
Greg Claytone04cfd22012-07-11 22:13:18 +0000116
117def append_regex_callback(option, opt, value, parser):
118 try:
119 ivar_regex = re.compile(value)
120 parser.values.ivar_regex_blacklist.append(ivar_regex)
121 except:
122 print 'error: an exception was thrown when compiling the ivar regular expression for "%s"' % value
Greg Claytonb403a152012-04-21 00:11:26 +0000123
Greg Claytond84bb482012-04-13 16:24:09 +0000124def add_common_options(parser):
125 parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
Greg Claytone04cfd22012-07-11 22:13:18 +0000126 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)
Greg Claytond84bb482012-04-13 16:24:09 +0000127 parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False)
128 parser.add_option('-m', '--memory', action='store_true', dest='memory', help='dump the memory for each matching block', default=False)
129 parser.add_option('-f', '--format', type='string', dest='format', help='the format to use when dumping memory if --memory is specified', default=None)
Greg Claytone04cfd22012-07-11 22:13:18 +0000130 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')
Greg Claytonb403a152012-04-21 00:11:26 +0000131 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)
Greg Claytond9fc5352012-05-10 23:17:28 +0000132 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)
Greg Claytone04cfd22012-07-11 22:13:18 +0000133 parser.add_option('-M', '--max-matches', type='int', dest='max_matches', help='the maximum number of matches to print', default=256)
Greg Claytond9fc5352012-05-10 23:17:28 +0000134
Greg Claytond9fc5352012-05-10 23:17:28 +0000135def dump_stack_history_entry(stack_history_entry, idx):
Greg Clayton7200ed12012-05-10 23:37:52 +0000136 address = int(stack_history_entry.address)
137 if address:
138 type_flags = int(stack_history_entry.type_flags)
Greg Claytond9fc5352012-05-10 23:17:28 +0000139 symbolicator = lldb.utils.symbolication.Symbolicator()
140 symbolicator.target = lldb.target
Greg Clayton341039f2012-05-11 02:42:36 +0000141 type_str = ''
142 if type_flags == 0:
143 type_str = 'free'
144 else:
145 if type_flags & 2:
146 type_str = 'alloc'
147 elif type_flags & 4:
148 type_str = 'free'
149 elif type_flags & 1:
150 type_str = 'generic'
151 else:
152 type_str = hex(type_flags)
153 print 'stack[%u]: addr = 0x%x, type=%s, frames:' % (idx, address, type_str)
Greg Claytond9fc5352012-05-10 23:17:28 +0000154 frame_idx = 0
Greg Clayton7200ed12012-05-10 23:37:52 +0000155 idx = 0
156 pc = int(stack_history_entry.frames[idx])
Greg Claytond9fc5352012-05-10 23:17:28 +0000157 while pc != 0:
158 if pc >= 0x1000:
159 frames = symbolicator.symbolicate(pc)
160 if frames:
161 for frame in frames:
Greg Clayton341039f2012-05-11 02:42:36 +0000162 print ' [%u] %s' % (frame_idx, frame)
Greg Claytond9fc5352012-05-10 23:17:28 +0000163 frame_idx += 1
164 else:
Greg Clayton341039f2012-05-11 02:42:36 +0000165 print ' [%u] 0x%x' % (frame_idx, pc)
Greg Claytond9fc5352012-05-10 23:17:28 +0000166 frame_idx += 1
Greg Clayton7200ed12012-05-10 23:37:52 +0000167 idx = idx + 1
168 pc = int(stack_history_entry.frames[idx])
Greg Claytond9fc5352012-05-10 23:17:28 +0000169 else:
170 pc = 0
Greg Clayton341039f2012-05-11 02:42:36 +0000171 print
Greg Claytond9fc5352012-05-10 23:17:28 +0000172
Greg Clayton341039f2012-05-11 02:42:36 +0000173def dump_stack_history_entries(addr, history):
Greg Claytond9fc5352012-05-10 23:17:28 +0000174 # malloc_stack_entry *get_stack_history_for_address (const void * addr)
Greg Clayton341039f2012-05-11 02:42:36 +0000175 expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
Greg Claytond9fc5352012-05-10 23:17:28 +0000176 expr_sbvalue = lldb.frame.EvaluateExpression (expr)
177 if expr_sbvalue.error.Success():
178 if expr_sbvalue.unsigned:
179 expr_value = lldb.value(expr_sbvalue)
180 idx = 0;
181 stack_history_entry = expr_value[idx]
Greg Clayton7200ed12012-05-10 23:37:52 +0000182 while int(stack_history_entry.address) != 0:
Greg Claytond9fc5352012-05-10 23:17:28 +0000183 dump_stack_history_entry(stack_history_entry, idx)
184 idx = idx + 1
185 stack_history_entry = expr_value[idx]
Greg Clayton341039f2012-05-11 02:42:36 +0000186 else:
187 print 'error: expression failed "%s" => %s' % (expr, expr_sbvalue.error)
Greg Claytond9fc5352012-05-10 23:17:28 +0000188
Greg Claytone04cfd22012-07-11 22:13:18 +0000189
190def display_match_results (options, arg_str_description, expr_sbvalue, print_no_matches = True):
Greg Clayton7fb671b2012-04-11 18:30:53 +0000191 if expr_sbvalue.error.Success():
192 if expr_sbvalue.unsigned:
193 match_value = lldb.value(expr_sbvalue)
194 i = 0
195 while 1:
Greg Claytone04cfd22012-07-11 22:13:18 +0000196 print_entry = True
Greg Clayton7fb671b2012-04-11 18:30:53 +0000197 match_entry = match_value[i]; i += 1
Greg Claytone04cfd22012-07-11 22:13:18 +0000198 if i >= options.max_matches:
199 print 'error: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches)
200 break
Greg Clayton7fb671b2012-04-11 18:30:53 +0000201 malloc_addr = match_entry.addr.sbvalue.unsigned
202 if malloc_addr == 0:
203 break
204 malloc_size = int(match_entry.size)
205 offset = int(match_entry.offset)
Greg Clayton94073022012-07-07 01:22:45 +0000206 match_addr = malloc_addr + offset
Greg Clayton7fb671b2012-04-11 18:30:53 +0000207 dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
Greg Clayton77677162012-04-12 18:57:36 +0000208 description = '[%u] %s: addr = 0x%x' % (i, arg_str_description, malloc_addr)
209 if offset != 0:
210 description += ' + %u' % (offset)
211 description += ', size = %u' % (malloc_size)
Greg Claytone04cfd22012-07-11 22:13:18 +0000212 derefed_dynamic_value = None
Greg Clayton94073022012-07-07 01:22:45 +0000213 if dynamic_value.type.name == 'void *':
Greg Clayton7fb671b2012-04-11 18:30:53 +0000214 if options.type == 'pointer' and malloc_size == 4096:
215 error = lldb.SBError()
216 data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
217 if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
Greg Clayton77677162012-04-12 18:57:36 +0000218 description += ', type = (AUTORELEASE!)'
Greg Clayton77677162012-04-12 18:57:36 +0000219 else:
Greg Clayton77677162012-04-12 18:57:36 +0000220 derefed_dynamic_value = dynamic_value.deref
Greg Clayton94073022012-07-07 01:22:45 +0000221 if derefed_dynamic_value:
Greg Clayton77677162012-04-12 18:57:36 +0000222 derefed_dynamic_type = derefed_dynamic_value.type
Greg Clayton94073022012-07-07 01:22:45 +0000223 derefed_dynamic_type_size = derefed_dynamic_type.size
224 derefed_dynamic_type_name = derefed_dynamic_type.name
225 description += ', type = %s <%u>' % (derefed_dynamic_type_name, derefed_dynamic_type_size)
226 if offset < derefed_dynamic_type_size:
227 member_list = list();
228 get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
229 if member_list:
230 member_path = ''
231 for member in member_list:
232 member_name = member.name
233 if member_name:
234 if member_path:
235 member_path += '.'
236 member_path += member_name
237 if member_path:
Greg Claytone04cfd22012-07-11 22:13:18 +0000238 if options.ivar_regex_blacklist:
239 for ivar_regex in options.ivar_regex_blacklist:
240 if ivar_regex.match(member_path):
241 print_entry = False
Greg Clayton94073022012-07-07 01:22:45 +0000242 description += ', ivar = %s' % (member_path)
Greg Claytone04cfd22012-07-11 22:13:18 +0000243 if print_entry:
244 if description:
245 print description
246 if options.print_type and derefed_dynamic_value:
247 print derefed_dynamic_value
248 if options.print_object_description and dynamic_value:
249 desc = dynamic_value.GetObjectDescription()
250 if desc:
251 print ' (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
252 if options.memory:
253 cmd_result = lldb.SBCommandReturnObject()
254 memory_command = "memory read -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
255 lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
256 print cmd_result.GetOutput()
257 if options.stack_history:
258 dump_stack_history_entries(malloc_addr, 1)
259 elif options.stack:
260 dump_stack_history_entries(malloc_addr, 0)
261 return i
262 elif print_no_matches:
263 print 'no matches found for %s' % (arg_str_description)
Greg Clayton7fb671b2012-04-11 18:30:53 +0000264 else:
Greg Clayton77677162012-04-12 18:57:36 +0000265 print expr_sbvalue.error
Greg Claytone04cfd22012-07-11 22:13:18 +0000266 return 0
267
268def heap_search(options, arg_str):
269 dylid_load_err = load_dylib()
270 if dylid_load_err:
271 print dylid_load_err
272 return
273 expr = None
274 arg_str_description = arg_str
275 if options.format == None:
276 options.format = "Y" # 'Y' is "bytes with ASCII" format
277 if options.type == 'pointer':
278 expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
279 arg_str_description = 'malloc block containing pointer %s' % arg_str
280 if options.format == None:
281 options.format = "A" # 'A' is "address" format
282 elif options.type == 'cstr':
283 expr = 'find_cstring_in_heap("%s")' % arg_str
284 arg_str_description = 'malloc block containing "%s"' % arg_str
285 elif options.type == 'addr':
286 expr = 'find_block_for_address((void *)%s)' % arg_str
287 arg_str_description = 'malloc block for %s' % arg_str
288 else:
289 print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
290 return
291
292 display_match_results (options, arg_str_description, lldb.frame.EvaluateExpression (expr))
Greg Clayton7fb671b2012-04-11 18:30:53 +0000293
Greg Clayton77677162012-04-12 18:57:36 +0000294def ptr_refs(debugger, command, result, dict):
Greg Clayton804de012012-04-11 16:27:06 +0000295 command_args = shlex.split(command)
Greg Clayton341039f2012-05-11 02:42:36 +0000296 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
Greg Clayton7fb671b2012-04-11 18:30:53 +0000297 description='''Searches the heap for pointer references on darwin user space programs.
298
299 Any matches that were found will dump the malloc blocks that contain the pointers
300 and might be able to print what kind of objects the pointers are contained in using
Greg Clayton77677162012-04-12 18:57:36 +0000301 dynamic type information in the program.'''
302 parser = optparse.OptionParser(description=description, prog='ptr_refs',usage=usage)
Greg Claytond84bb482012-04-13 16:24:09 +0000303 add_common_options(parser)
Greg Clayton804de012012-04-11 16:27:06 +0000304 try:
305 (options, args) = parser.parse_args(command_args)
306 except:
307 return
Greg Clayton7fb671b2012-04-11 18:30:53 +0000308
309 options.type = 'pointer'
Greg Clayton804de012012-04-11 16:27:06 +0000310
311 if args:
312
313 for data in args:
Greg Clayton7fb671b2012-04-11 18:30:53 +0000314 heap_search (options, data)
Greg Clayton804de012012-04-11 16:27:06 +0000315 else:
Greg Clayton7fb671b2012-04-11 18:30:53 +0000316 print 'error: no pointer arguments were given'
Greg Clayton804de012012-04-11 16:27:06 +0000317
Greg Clayton77677162012-04-12 18:57:36 +0000318def cstr_refs(debugger, command, result, dict):
Greg Clayton7fb671b2012-04-11 18:30:53 +0000319 command_args = shlex.split(command)
Greg Clayton77677162012-04-12 18:57:36 +0000320 usage = "usage: %prog [options] <CSTR> [CSTR ...]"
Greg Clayton7fb671b2012-04-11 18:30:53 +0000321 description='''Searches the heap for C string references on darwin user space programs.
322
323 Any matches that were found will dump the malloc blocks that contain the C strings
324 and might be able to print what kind of objects the pointers are contained in using
Greg Clayton77677162012-04-12 18:57:36 +0000325 dynamic type information in the program.'''
326 parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
Greg Claytond84bb482012-04-13 16:24:09 +0000327 add_common_options(parser)
Greg Clayton7fb671b2012-04-11 18:30:53 +0000328 try:
329 (options, args) = parser.parse_args(command_args)
330 except:
331 return
332
333 options.type = 'cstr'
334
335 if args:
336
337 for data in args:
338 heap_search (options, data)
339 else:
340 print 'error: no c string arguments were given to search for'
Greg Clayton804de012012-04-11 16:27:06 +0000341
Greg Clayton77677162012-04-12 18:57:36 +0000342def malloc_info(debugger, command, result, dict):
343 command_args = shlex.split(command)
Greg Clayton341039f2012-05-11 02:42:36 +0000344 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
Greg Clayton77677162012-04-12 18:57:36 +0000345 description='''Searches the heap a malloc block that contains the addresses specified as arguments.
346
347 Any matches that were found will dump the malloc blocks that match or contain
348 the specified address. The matching blocks might be able to show what kind
349 of objects they are using dynamic type information in the program.'''
350 parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
Greg Claytond84bb482012-04-13 16:24:09 +0000351 add_common_options(parser)
Greg Clayton77677162012-04-12 18:57:36 +0000352 try:
353 (options, args) = parser.parse_args(command_args)
354 except:
355 return
Greg Clayton77677162012-04-12 18:57:36 +0000356 options.type = 'addr'
Greg Clayton77677162012-04-12 18:57:36 +0000357 if args:
Greg Clayton77677162012-04-12 18:57:36 +0000358 for data in args:
359 heap_search (options, data)
360 else:
361 print 'error: no c string arguments were given to search for'
362
Greg Clayton341039f2012-05-11 02:42:36 +0000363def malloc_history(debugger, command, result, dict):
364 command_args = shlex.split(command)
365 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
366 description='''Gets the allocation history for an expression whose result is an address.
367
368 Programs should set the MallocStackLoggingNoCompact=1 in the environment to enable stack history. This can be done
369 with "process launch -v MallocStackLoggingNoCompact=1 -- [arg1 ...]"'''
370
371 dylid_load_err = load_dylib()
372 if dylid_load_err:
373 print dylid_load_err
374 else:
375 if command_args:
376 for addr_expr_str in command_args:
377 expr_sbvalue = lldb.frame.EvaluateExpression (addr_expr_str)
378 if expr_sbvalue.error.Success():
379 addr = expr_sbvalue.unsigned
380 if addr != 0:
381 dump_stack_history_entries (addr, 1)
382 else:
383 print 'error: expression error for "%s": %s' % (addr_expr_str, expr_sbvalue.error)
384 else:
385 print 'error: no address expressions were specified'
386
Greg Claytone04cfd22012-07-11 22:13:18 +0000387def section_ptr_refs(debugger, command, result, dict):
388 command_args = shlex.split(command)
389 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
390 description='''Searches section contents for pointer values in darwin user space programs.'''
391 parser = optparse.OptionParser(description=description, prog='section_ptr_refs',usage=usage)
392 add_common_options(parser)
393 parser.add_option('--section', action='append', type='string', dest='section_names', help='section name to search', default=list())
394 try:
395 (options, args) = parser.parse_args(command_args)
396 except:
397 return
398
399 options.type = 'pointer'
400
401 sections = list()
402 section_modules = list()
403 if not options.section_names:
404 print 'error: at least one section must be specified with the --section option'
405 return
406
407 for module in lldb.target.modules:
408 for section_name in options.section_names:
409 section = module.section[section_name]
410 if section:
411 sections.append (section)
412 section_modules.append (module)
413 if sections:
414 dylid_load_err = load_dylib()
415 if dylid_load_err:
416 print dylid_load_err
417 return
418 for expr_str in args:
419 for (idx, section) in enumerate(sections):
420 expr = 'find_pointer_in_memory(0x%xllu, %ullu, (void *)%s)' % (section.addr.load_addr, section.size, expr_str)
421 arg_str_description = 'section %s.%s containing "%s"' % (section_modules[idx].file.fullpath, section.name, expr_str)
422 num_matches = display_match_results (options, arg_str_description, lldb.frame.EvaluateExpression (expr), False)
423 if num_matches:
424 if num_matches < options.max_matches:
425 options.max_matches = options.max_matches - num_matches
426 else:
427 options.max_matches = 0
428 if options.max_matches == 0:
429 return
430 else:
431 print 'error: no sections were found that match any of %s' % (', '.join(options.section_names))
432
Greg Claytond712ef02012-04-25 18:40:20 +0000433if __name__ == '__main__':
434 lldb.debugger = lldb.SBDebugger.Create()
435
436# This initializer is being run from LLDB in the embedded command interpreter
437# Add any commands contained in this module to LLDB
438lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.ptr_refs ptr_refs')
439lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.cstr_refs cstr_refs')
440lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_info malloc_info')
Greg Clayton341039f2012-05-11 02:42:36 +0000441lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_history malloc_history')
Greg Claytone04cfd22012-07-11 22:13:18 +0000442lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.section_ptr_refs section_ptr_refs')
443print '"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.'
Greg Clayton804de012012-04-11 16:27:06 +0000444
445
446
447