blob: c829cc8f00124051c7d7b0b80fccf47757b8976a [file] [log] [blame]
Greg Claytone93e24f2012-04-11 16:27:06 +00001#!/usr/bin/python
2
3#----------------------------------------------------------------------
Greg Clayton1dae6f32012-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 Claytone93e24f2012-04-11 16:27:06 +00007#
Greg Clayton1dae6f32012-04-25 18:40:20 +00008# (lldb) script import lldb.macosx.heap
Greg Claytone93e24f2012-04-11 16:27:06 +00009#----------------------------------------------------------------------
10
11import lldb
12import commands
13import optparse
Greg Clayton96666442012-04-11 18:30:53 +000014import os
Greg Clayton1dae6f32012-04-25 18:40:20 +000015import os.path
Greg Clayton4c5c4292012-07-11 22:13:18 +000016import re
Greg Claytone93e24f2012-04-11 16:27:06 +000017import shlex
Greg Clayton1dae6f32012-04-25 18:40:20 +000018import string
19import tempfile
Greg Clayton6f2f0ab2012-04-25 01:49:50 +000020import lldb.utils.symbolication
Greg Claytone93e24f2012-04-11 16:27:06 +000021
Greg Clayton1dae6f32012-04-25 18:40:20 +000022g_libheap_dylib_dir = None
23g_libheap_dylib_dict = dict()
Greg Claytonbf479652012-05-11 02:42:36 +000024g_verbose = False
Greg Clayton1dae6f32012-04-25 18:40:20 +000025
Greg Clayton9098fee2012-04-21 00:11:26 +000026def load_dylib():
27 if lldb.target:
Greg Clayton1dae6f32012-04-25 18:40:20 +000028 global g_libheap_dylib_dir
29 global g_libheap_dylib_dict
30 triple = lldb.target.triple
Greg Clayton3e339792012-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 Clayton1dae6f32012-04-25 18:40:20 +000034 if not g_libheap_dylib_dir:
Greg Clayton3e339792012-04-25 21:23:07 +000035 g_libheap_dylib_dir = tempfile.gettempdir() + '/lldb-dylibs'
36 triple_dir = g_libheap_dylib_dir + '/' + triple + '/' + __name__
Greg Clayton1dae6f32012-04-25 18:40:20 +000037 if not os.path.exists(triple_dir):
Greg Clayton3e339792012-04-25 21:23:07 +000038 os.makedirs(triple_dir)
Greg Clayton1dae6f32012-04-25 18:40:20 +000039 libheap_dylib_path = triple_dir + '/libheap.dylib'
40 g_libheap_dylib_dict[triple] = libheap_dylib_path
Greg Clayton3e339792012-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 Clayton1dae6f32012-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 Clayton3e339792012-04-25 21:23:07 +000047 # print make_command
Greg Clayton0cae0632012-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 Clayton9098fee2012-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 Claytonbf479652012-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 Clayton0d0f56d2012-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 Clayton4c5c4292012-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 Clayton9098fee2012-04-21 00:11:26 +0000123
Greg Clayton93e5ba52012-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 Clayton4c5c4292012-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 Clayton93e5ba52012-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 Clayton4c5c4292012-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 Clayton9098fee2012-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 Clayton7a245762012-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 Clayton4c5c4292012-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 Clayton7a245762012-05-10 23:17:28 +0000134
Greg Clayton7a245762012-05-10 23:17:28 +0000135def dump_stack_history_entry(stack_history_entry, idx):
Greg Clayton6f446f32012-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 Clayton7a245762012-05-10 23:17:28 +0000139 symbolicator = lldb.utils.symbolication.Symbolicator()
140 symbolicator.target = lldb.target
Greg Claytonbf479652012-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 Clayton7a245762012-05-10 23:17:28 +0000154 frame_idx = 0
Greg Clayton6f446f32012-05-10 23:37:52 +0000155 idx = 0
156 pc = int(stack_history_entry.frames[idx])
Greg Clayton7a245762012-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 Claytonbf479652012-05-11 02:42:36 +0000162 print ' [%u] %s' % (frame_idx, frame)
Greg Clayton7a245762012-05-10 23:17:28 +0000163 frame_idx += 1
164 else:
Greg Claytonbf479652012-05-11 02:42:36 +0000165 print ' [%u] 0x%x' % (frame_idx, pc)
Greg Clayton7a245762012-05-10 23:17:28 +0000166 frame_idx += 1
Greg Clayton6f446f32012-05-10 23:37:52 +0000167 idx = idx + 1
168 pc = int(stack_history_entry.frames[idx])
Greg Clayton7a245762012-05-10 23:17:28 +0000169 else:
170 pc = 0
Greg Claytonbf479652012-05-11 02:42:36 +0000171 print
Greg Clayton7a245762012-05-10 23:17:28 +0000172
Greg Claytonbf479652012-05-11 02:42:36 +0000173def dump_stack_history_entries(addr, history):
Greg Clayton7a245762012-05-10 23:17:28 +0000174 # malloc_stack_entry *get_stack_history_for_address (const void * addr)
Greg Claytonbf479652012-05-11 02:42:36 +0000175 expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
Greg Clayton7a245762012-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 Clayton6f446f32012-05-10 23:37:52 +0000182 while int(stack_history_entry.address) != 0:
Greg Clayton7a245762012-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 Claytonbf479652012-05-11 02:42:36 +0000186 else:
187 print 'error: expression failed "%s" => %s' % (expr, expr_sbvalue.error)
Greg Clayton7a245762012-05-10 23:17:28 +0000188
Greg Clayton4c5c4292012-07-11 22:13:18 +0000189
190def display_match_results (options, arg_str_description, expr_sbvalue, print_no_matches = True):
Greg Clayton96666442012-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 Clayton4c5c4292012-07-11 22:13:18 +0000196 print_entry = True
Greg Clayton96666442012-04-11 18:30:53 +0000197 match_entry = match_value[i]; i += 1
Greg Clayton4c5c4292012-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 Clayton96666442012-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 Clayton0d0f56d2012-07-07 01:22:45 +0000206 match_addr = malloc_addr + offset
Greg Clayton96666442012-04-11 18:30:53 +0000207 dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
Greg Claytonbff78412012-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 Clayton4c5c4292012-07-11 22:13:18 +0000212 derefed_dynamic_value = None
Greg Clayton0d0f56d2012-07-07 01:22:45 +0000213 if dynamic_value.type.name == 'void *':
Greg Clayton96666442012-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 Claytonbff78412012-04-12 18:57:36 +0000218 description += ', type = (AUTORELEASE!)'
Greg Claytonbff78412012-04-12 18:57:36 +0000219 else:
Greg Claytonbff78412012-04-12 18:57:36 +0000220 derefed_dynamic_value = dynamic_value.deref
Greg Clayton0d0f56d2012-07-07 01:22:45 +0000221 if derefed_dynamic_value:
Greg Claytonbff78412012-04-12 18:57:36 +0000222 derefed_dynamic_type = derefed_dynamic_value.type
Greg Clayton0d0f56d2012-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 Clayton4c5c4292012-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 Clayton0d0f56d2012-07-07 01:22:45 +0000242 description += ', ivar = %s' % (member_path)
Greg Clayton4c5c4292012-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 Clayton96666442012-04-11 18:30:53 +0000264 else:
Greg Claytonbff78412012-04-12 18:57:36 +0000265 print expr_sbvalue.error
Greg Clayton4c5c4292012-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 Clayton96666442012-04-11 18:30:53 +0000293
Greg Claytonbff78412012-04-12 18:57:36 +0000294def ptr_refs(debugger, command, result, dict):
Greg Claytone93e24f2012-04-11 16:27:06 +0000295 command_args = shlex.split(command)
Greg Claytonbf479652012-05-11 02:42:36 +0000296 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
Greg Clayton96666442012-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 Claytonbff78412012-04-12 18:57:36 +0000301 dynamic type information in the program.'''
302 parser = optparse.OptionParser(description=description, prog='ptr_refs',usage=usage)
Greg Clayton93e5ba52012-04-13 16:24:09 +0000303 add_common_options(parser)
Greg Claytone93e24f2012-04-11 16:27:06 +0000304 try:
305 (options, args) = parser.parse_args(command_args)
306 except:
307 return
Greg Clayton96666442012-04-11 18:30:53 +0000308
309 options.type = 'pointer'
Greg Claytone93e24f2012-04-11 16:27:06 +0000310
311 if args:
312
313 for data in args:
Greg Clayton96666442012-04-11 18:30:53 +0000314 heap_search (options, data)
Greg Claytone93e24f2012-04-11 16:27:06 +0000315 else:
Greg Clayton96666442012-04-11 18:30:53 +0000316 print 'error: no pointer arguments were given'
Greg Claytone93e24f2012-04-11 16:27:06 +0000317
Greg Claytonbff78412012-04-12 18:57:36 +0000318def cstr_refs(debugger, command, result, dict):
Greg Clayton96666442012-04-11 18:30:53 +0000319 command_args = shlex.split(command)
Greg Claytonbff78412012-04-12 18:57:36 +0000320 usage = "usage: %prog [options] <CSTR> [CSTR ...]"
Greg Clayton96666442012-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 Claytonbff78412012-04-12 18:57:36 +0000325 dynamic type information in the program.'''
326 parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
Greg Clayton93e5ba52012-04-13 16:24:09 +0000327 add_common_options(parser)
Greg Clayton96666442012-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 Claytone93e24f2012-04-11 16:27:06 +0000341
Greg Claytonbff78412012-04-12 18:57:36 +0000342def malloc_info(debugger, command, result, dict):
343 command_args = shlex.split(command)
Greg Claytonbf479652012-05-11 02:42:36 +0000344 usage = "usage: %prog [options] <EXPR> [EXPR ...]"
Greg Claytonbff78412012-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 Clayton93e5ba52012-04-13 16:24:09 +0000351 add_common_options(parser)
Greg Claytonbff78412012-04-12 18:57:36 +0000352 try:
353 (options, args) = parser.parse_args(command_args)
354 except:
355 return
Greg Claytonbff78412012-04-12 18:57:36 +0000356 options.type = 'addr'
Greg Claytonbff78412012-04-12 18:57:36 +0000357 if args:
Greg Claytonbff78412012-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 Claytonbf479652012-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 Clayton4c5c4292012-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 Clayton1dae6f32012-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 Claytonbf479652012-05-11 02:42:36 +0000441lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_history malloc_history')
Greg Clayton4c5c4292012-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 Claytone93e24f2012-04-11 16:27:06 +0000444
445
446
447