heap.py revision bff78410b94d0b52956e3c6f2966b25a9b799366
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
23e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
249666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Claytondef heap_search(options, arg_str):
259666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    expr = None
26bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    arg_str_description = arg_str
279666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    if options.type == 'pointer':
28bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        expr = 'find_pointer_in_heap(%s)' % arg_str
29bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        arg_str_description = 'malloc block containing pointer %s' % arg_str
309666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    elif options.type == 'cstr':
319666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        expr = 'find_cstring_in_heap("%s")' % arg_str
32bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        arg_str_description = 'malloc block containing "%s"' % arg_str
33bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    elif options.type == 'addr':
34bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        expr = 'find_block_for_address(%s)' % arg_str
35bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        arg_str_description = 'malloc block for %s' % arg_str
369666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    else:
379666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
389666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        return
399666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
409666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    expr_sbvalue = lldb.frame.EvaluateExpression (expr)
419666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    if expr_sbvalue.error.Success():
429666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        if expr_sbvalue.unsigned:
439666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            match_value = lldb.value(expr_sbvalue)
449666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            i = 0
459666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            while 1:
469666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                match_entry = match_value[i]; i += 1
479666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                malloc_addr = match_entry.addr.sbvalue.unsigned
489666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                if malloc_addr == 0:
499666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                    break
509666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                malloc_size = int(match_entry.size)
519666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                offset = int(match_entry.offset)
529666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
539666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                # If the type is still 'void *' then we weren't able to figure
549666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                # out a dynamic type for the malloc_addr
559666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                type_name = dynamic_value.type.name
56bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                description = '[%u] %s: addr = 0x%x' % (i, arg_str_description, malloc_addr)
57bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                if offset != 0:
58bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    description += ' + %u' % (offset)
59bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                description += ', size = %u' % (malloc_size)
609666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                if type_name == 'void *':
619666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                    if options.type == 'pointer' and malloc_size == 4096:
629666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                        error = lldb.SBError()
639666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                        data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
649666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                        if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
65bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            description += ', type = (AUTORELEASE!)'
66bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            print description
679666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                            continue
68bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                else:
69bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    description += ', type = %s' % (type_name)
70bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    derefed_dynamic_value = dynamic_value.deref
71bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    ivar_member = None
72bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    if derefed_dynamic_value:
73bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        derefed_dynamic_type = derefed_dynamic_value.type
74bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        member = derefed_dynamic_type.GetFieldAtIndex(0)
75bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        search_bases = False
76bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        if member:
77bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            if member.GetOffsetInBytes() <= offset:
78bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                for field_idx in range (derefed_dynamic_type.GetNumberOfFields()):
79bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    member = derefed_dynamic_type.GetFieldAtIndex(field_idx)
80bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    member_byte_offset = member.GetOffsetInBytes()
81bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    if member_byte_offset == offset:
82bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                        ivar_member = member
83bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                        break
84bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            else:
85bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                search_bases = True
869666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                        else:
879666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                            search_bases = True
88bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
89bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        if not ivar_member and search_bases:
90bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            for field_idx in range (derefed_dynamic_type.GetNumberOfDirectBaseClasses()):
91bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                member = derefed_dynamic_type.GetDirectBaseClassAtIndex(field_idx)
929666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                                member_byte_offset = member.GetOffsetInBytes()
939666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                                if member_byte_offset == offset:
949666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                                    ivar_member = member
959666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                                    break
96bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            if not ivar_member:
97bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                for field_idx in range (derefed_dynamic_type.GetNumberOfVirtualBaseClasses()):
98bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    member = derefed_dynamic_type.GetVirtualBaseClassAtIndex(field_idx)
99bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    member_byte_offset = member.GetOffsetInBytes()
100bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                    if member_byte_offset == offset:
101bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                        ivar_member = member
102bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                                        break
1039666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton                    if ivar_member:
104bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        description +=', ivar = %s' % (ivar_member.name)
105bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
106bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    print description
107bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    if derefed_dynamic_value:
108bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        print derefed_dynamic_value
109bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                    if options.print_object_description:
110bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        desc = dynamic_value.GetObjectDescription()
111bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                        if desc:
112bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton                            print '  (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
1139666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        else:
1149666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            print '%s %s was not found in any malloc blocks' % (options.type, arg_str)
1159666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    else:
116bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        print expr_sbvalue.error
117bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    print
1189666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
119bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef ptr_refs(debugger, command, result, dict):
120e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    command_args = shlex.split(command)
121bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    usage = "usage: %prog [options] <PTR> [PTR ...]"
1229666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    description='''Searches the heap for pointer references on darwin user space programs.
1239666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
1249666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    Any matches that were found will dump the malloc blocks that contain the pointers
1259666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    and might be able to print what kind of objects the pointers are contained in using
126bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    dynamic type information in the program.'''
127bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser = optparse.OptionParser(description=description, prog='ptr_refs',usage=usage)
128e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
1299666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False)
130bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser.add_option('-m', '--memory', action='store_true', dest='show_memory', help='dump the memory for each matching block', default=False)
131e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    try:
132e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton        (options, args) = parser.parse_args(command_args)
133e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    except:
134e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton        return
1359666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
1369666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    options.type = 'pointer'
137e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
138e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    if args:
139e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
140e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton        for data in args:
1419666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            heap_search (options, data)
142e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    else:
1439666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        print 'error: no pointer arguments were given'
1449666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
145bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef cstr_refs(debugger, command, result, dict):
1469666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    command_args = shlex.split(command)
147bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    usage = "usage: %prog [options] <CSTR> [CSTR ...]"
1489666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    description='''Searches the heap for C string references on darwin user space programs.
1499666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
1509666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    Any matches that were found will dump the malloc blocks that contain the C strings
1519666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    and might be able to print what kind of objects the pointers are contained in using
152bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    dynamic type information in the program.'''
153bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
1549666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
1559666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False)
156bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser.add_option('-m', '--memory', action='store_true', dest='show_memory', help='dump the memory for each matching block', default=False)
1579666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    try:
1589666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        (options, args) = parser.parse_args(command_args)
1599666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    except:
1609666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        return
1619666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
1629666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    options.type = 'cstr'
163e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
1649666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    if args:
1659666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton
1669666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        for data in args:
1679666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton            heap_search (options, data)
1689666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    else:
1699666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton        print 'error: no c string arguments were given to search for'
170e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
171bff78410b94d0b52956e3c6f2966b25a9b799366Greg Claytondef malloc_info(debugger, command, result, dict):
172bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    command_args = shlex.split(command)
173bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    usage = "usage: %prog [options] <ADDR> [ADDR ...]"
174bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    description='''Searches the heap a malloc block that contains the addresses specified as arguments.
175bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
176bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    Any matches that were found will dump the malloc blocks that match or contain
177bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    the specified address. The matching blocks might be able to show what kind
178bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    of objects they are using dynamic type information in the program.'''
179bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
180bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
181bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser.add_option('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', default=False)
182bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    parser.add_option('-m', '--memory', action='store_true', dest='show_memory', help='dump the memory for each matching block', default=False)
183bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    try:
184bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        (options, args) = parser.parse_args(command_args)
185bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    except:
186bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        return
187bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
188bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    options.type = 'addr'
189bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
190bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    if args:
191bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
192bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        for data in args:
193bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton            heap_search (options, data)
194bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    else:
195bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton        print 'error: no c string arguments were given to search for'
196bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton
197e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Claytondef __lldb_init_module (debugger, dict):
198e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    # This initializer is being run from LLDB in the embedded command interpreter
199e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton    # Add any commands contained in this module to LLDB
2009666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    libheap_dylib_path = os.path.dirname(__file__) + '/libheap.dylib'
2019666644d2b0da00eb0792f4de6f5b3cb98ac5fa0Greg Clayton    debugger.HandleCommand('process load "%s"' % libheap_dylib_path)
202bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    debugger.HandleCommand('command script add -f heap.ptr_refs ptr_refs')
203bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    debugger.HandleCommand('command script add -f heap.cstr_refs cstr_refs')
204bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    debugger.HandleCommand('command script add -f heap.malloc_info malloc_info')
205bff78410b94d0b52956e3c6f2966b25a9b799366Greg Clayton    print '"ptr_refs", "cstr_refs", and "malloc_info" commands have been installed, use the "--help" options on these commands for detailed help.'
206e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
207e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
208e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
209e93e24fb12f05cf363bc99e9c792c28cacace0c3Greg Clayton
210