#!/usr/bin/python

#----------------------------------------------------------------------
# This module is designed to live inside the "lldb" python package
# in the "lldb.macosx" package. To use this in the embedded python
# interpreter using "lldb" just import it:
#
#   (lldb) script import lldb.macosx.heap
#----------------------------------------------------------------------

import lldb
import commands
import optparse
import os
import os.path
import re
import shlex
import string
import sys
import tempfile
import lldb.utils.symbolication

g_libheap_dylib_dir = None
g_libheap_dylib_dict = dict()


def get_iterate_memory_expr(
        options,
        process,
        user_init_code,
        user_return_code):
    expr = '''
typedef unsigned natural_t;
typedef uintptr_t vm_size_t;
typedef uintptr_t vm_address_t;
typedef natural_t task_t;
typedef int kern_return_t;
#define KERN_SUCCESS 0
typedef void (*range_callback_t)(task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size);
'''
    if options.search_vm_regions:
        expr += '''
typedef int vm_prot_t;
typedef unsigned int vm_inherit_t;
typedef unsigned long long	memory_object_offset_t;
typedef unsigned int boolean_t;
typedef int vm_behavior_t;
typedef uint32_t vm32_object_id_t;
typedef natural_t mach_msg_type_number_t;
typedef uint64_t mach_vm_address_t;
typedef uint64_t mach_vm_offset_t;
typedef uint64_t mach_vm_size_t;
typedef uint64_t vm_map_offset_t;
typedef uint64_t vm_map_address_t;
typedef uint64_t vm_map_size_t;
#define	VM_PROT_NONE ((vm_prot_t) 0x00)
#define VM_PROT_READ ((vm_prot_t) 0x01)
#define VM_PROT_WRITE ((vm_prot_t) 0x02)
#define VM_PROT_EXECUTE ((vm_prot_t) 0x04)
typedef struct vm_region_submap_short_info_data_64_t {
    vm_prot_t protection;
    vm_prot_t max_protection;
    vm_inherit_t inheritance;
    memory_object_offset_t offset;		// offset into object/map
    unsigned int user_tag;	// user tag on map entry
    unsigned int ref_count;	 // obj/map mappers, etc
    unsigned short shadow_depth; 	// only for obj
    unsigned char external_pager;  // only for obj
    unsigned char share_mode;	// see enumeration
    boolean_t is_submap;	// submap vs obj
    vm_behavior_t behavior;	// access behavior hint
    vm32_object_id_t object_id;	// obj/map name, not a handle
    unsigned short user_wired_count;
} vm_region_submap_short_info_data_64_t;
#define VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 ((mach_msg_type_number_t)(sizeof(vm_region_submap_short_info_data_64_t)/sizeof(int)))'''
        if user_init_code:
            expr += user_init_code
        expr += '''
task_t task = (task_t)mach_task_self();
mach_vm_address_t vm_region_base_addr;
mach_vm_size_t vm_region_size;
natural_t vm_region_depth;
vm_region_submap_short_info_data_64_t vm_region_info;
kern_return_t err;
for (vm_region_base_addr = 0, vm_region_size = 1; vm_region_size != 0; vm_region_base_addr += vm_region_size)
{
    mach_msg_type_number_t vm_region_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
    err = (kern_return_t)mach_vm_region_recurse (task,
                                                 &vm_region_base_addr,
                                                 &vm_region_size,
                                                 &vm_region_depth,
                                                 &vm_region_info,
                                                 &vm_region_info_size);
    if (err)
        break;
    // Check all read + write regions. This will cover the thread stacks
    // and any regions of memory like __DATA segments, that might contain
    // data we are looking for
    if (vm_region_info.protection & VM_PROT_WRITE &&
        vm_region_info.protection & VM_PROT_READ)
    {
        baton.callback (task,
                        &baton,
                        64,
                        vm_region_base_addr,
                        vm_region_size);
    }
}'''
    else:
        if options.search_stack:
            expr += get_thread_stack_ranges_struct(process)
        if options.search_segments:
            expr += get_sections_ranges_struct(process)
        if user_init_code:
            expr += user_init_code
        if options.search_heap:
            expr += '''
#define MALLOC_PTR_IN_USE_RANGE_TYPE 1
typedef struct vm_range_t {
    vm_address_t	address;
    vm_size_t		size;
} vm_range_t;
typedef kern_return_t (*memory_reader_t)(task_t task, vm_address_t remote_address, vm_size_t size, void **local_memory);
typedef void (*vm_range_recorder_t)(task_t task, void *baton, unsigned type, vm_range_t *range, unsigned size);
typedef struct malloc_introspection_t {
    kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */
} malloc_introspection_t;
typedef struct malloc_zone_t {
    void *reserved1[12];
    struct malloc_introspection_t	*introspect;
} malloc_zone_t;
memory_reader_t task_peek = [](task_t task, vm_address_t remote_address, vm_size_t size, void **local_memory) -> kern_return_t {
    *local_memory = (void*) remote_address;
    return KERN_SUCCESS;
};
vm_address_t *zones = 0;
unsigned int num_zones = 0;task_t task = 0;
kern_return_t err = (kern_return_t)malloc_get_all_zones (task, task_peek, &zones, &num_zones);
if (KERN_SUCCESS == err)
{
    for (unsigned int i=0; i<num_zones; ++i)
    {
        const malloc_zone_t *zone = (const malloc_zone_t *)zones[i];
        if (zone && zone->introspect)
            zone->introspect->enumerator (task,
                                          &baton,
                                          MALLOC_PTR_IN_USE_RANGE_TYPE,
                                          (vm_address_t)zone,
                                          task_peek,
                                          [] (task_t task, void *baton, unsigned type, vm_range_t *ranges, unsigned size) -> void
                                          {
                                              range_callback_t callback = ((callback_baton_t *)baton)->callback;
                                              for (unsigned i=0; i<size; ++i)
                                              {
                                                  callback (task, baton, type, ranges[i].address, ranges[i].size);
                                              }
                                          });
    }
}'''

        if options.search_stack:
            expr += '''
#ifdef NUM_STACKS
// Call the callback for the thread stack ranges
for (uint32_t i=0; i<NUM_STACKS; ++i) {
    range_callback(task, &baton, 8, stacks[i].base, stacks[i].size);
    if (STACK_RED_ZONE_SIZE > 0) {
        range_callback(task, &baton, 16, stacks[i].base - STACK_RED_ZONE_SIZE, STACK_RED_ZONE_SIZE);
    }
}
#endif'''

        if options.search_segments:
            expr += '''
#ifdef NUM_SEGMENTS
// Call the callback for all segments
for (uint32_t i=0; i<NUM_SEGMENTS; ++i)
    range_callback(task, &baton, 32, segments[i].base, segments[i].size);
#endif'''

    if user_return_code:
        expr += "\n%s" % (user_return_code,)

    return expr


def get_member_types_for_offset(value_type, offset, member_list):
    member = value_type.GetFieldAtIndex(0)
    search_bases = False
    if member:
        if member.GetOffsetInBytes() <= offset:
            for field_idx in range(value_type.GetNumberOfFields()):
                member = value_type.GetFieldAtIndex(field_idx)
                member_byte_offset = member.GetOffsetInBytes()
                member_end_byte_offset = member_byte_offset + member.type.size
                if member_byte_offset <= offset and offset < member_end_byte_offset:
                    member_list.append(member)
                    get_member_types_for_offset(
                        member.type, offset - member_byte_offset, member_list)
                    return
        else:
            search_bases = True
    else:
        search_bases = True
    if search_bases:
        for field_idx in range(value_type.GetNumberOfDirectBaseClasses()):
            member = value_type.GetDirectBaseClassAtIndex(field_idx)
            member_byte_offset = member.GetOffsetInBytes()
            member_end_byte_offset = member_byte_offset + member.type.size
            if member_byte_offset <= offset and offset < member_end_byte_offset:
                member_list.append(member)
                get_member_types_for_offset(
                    member.type, offset - member_byte_offset, member_list)
                return
        for field_idx in range(value_type.GetNumberOfVirtualBaseClasses()):
            member = value_type.GetVirtualBaseClassAtIndex(field_idx)
            member_byte_offset = member.GetOffsetInBytes()
            member_end_byte_offset = member_byte_offset + member.type.size
            if member_byte_offset <= offset and offset < member_end_byte_offset:
                member_list.append(member)
                get_member_types_for_offset(
                    member.type, offset - member_byte_offset, member_list)
                return


def append_regex_callback(option, opt, value, parser):
    try:
        ivar_regex = re.compile(value)
        parser.values.ivar_regex_blacklist.append(ivar_regex)
    except:
        print 'error: an exception was thrown when compiling the ivar regular expression for "%s"' % value


def add_common_options(parser):
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    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)
    parser.add_option(
        '-o',
        '--po',
        action='store_true',
        dest='print_object_description',
        help='print the object descriptions for any matches',
        default=False)
    parser.add_option(
        '-z',
        '--size',
        action='store_true',
        dest='show_size',
        help='print the allocation size in bytes',
        default=False)
    parser.add_option(
        '-r',
        '--range',
        action='store_true',
        dest='show_range',
        help='print the allocation address range instead of just the allocation base address',
        default=False)
    parser.add_option(
        '-m',
        '--memory',
        action='store_true',
        dest='memory',
        help='dump the memory for each matching block',
        default=False)
    parser.add_option(
        '-f',
        '--format',
        type='string',
        dest='format',
        help='the format to use when dumping memory if --memory is specified',
        default=None)
    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')
    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)
    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)
    parser.add_option(
        '-F',
        '--max-frames',
        type='int',
        dest='max_frames',
        help='the maximum number of stack frames to print when using the --stack or --stack-history options (default=128)',
        default=128)
    parser.add_option(
        '-H',
        '--max-history',
        type='int',
        dest='max_history',
        help='the maximum number of stack history backtraces to print for each allocation when using the --stack-history option (default=16)',
        default=16)
    parser.add_option(
        '-M',
        '--max-matches',
        type='int',
        dest='max_matches',
        help='the maximum number of matches to print',
        default=32)
    parser.add_option(
        '-O',
        '--offset',
        type='int',
        dest='offset',
        help='the matching data must be at this offset',
        default=-1)
    parser.add_option(
        '--ignore-stack',
        action='store_false',
        dest='search_stack',
        help="Don't search the stack when enumerating memory",
        default=True)
    parser.add_option(
        '--ignore-heap',
        action='store_false',
        dest='search_heap',
        help="Don't search the heap allocations when enumerating memory",
        default=True)
    parser.add_option(
        '--ignore-segments',
        action='store_false',
        dest='search_segments',
        help="Don't search readable executable segments enumerating memory",
        default=True)
    parser.add_option(
        '-V',
        '--vm-regions',
        action='store_true',
        dest='search_vm_regions',
        help='Check all VM regions instead of searching the heap, stack and segments',
        default=False)


def type_flags_to_string(type_flags):
    if type_flags == 0:
        type_str = 'free'
    elif type_flags & 2:
        type_str = 'malloc'
    elif type_flags & 4:
        type_str = 'free'
    elif type_flags & 1:
        type_str = 'generic'
    elif type_flags & 8:
        type_str = 'stack'
    elif type_flags & 16:
        type_str = 'stack (red zone)'
    elif type_flags & 32:
        type_str = 'segment'
    elif type_flags & 64:
        type_str = 'vm_region'
    else:
        type_str = hex(type_flags)
    return type_str


def find_variable_containing_address(verbose, frame, match_addr):
    variables = frame.GetVariables(True, True, True, True)
    matching_var = None
    for var in variables:
        var_addr = var.GetLoadAddress()
        if var_addr != lldb.LLDB_INVALID_ADDRESS:
            byte_size = var.GetType().GetByteSize()
            if verbose:
                print 'frame #%u: [%#x - %#x) %s' % (frame.GetFrameID(), var.load_addr, var.load_addr + byte_size, var.name)
            if var_addr == match_addr:
                if verbose:
                    print 'match'
                return var
            else:
                if byte_size > 0 and var_addr <= match_addr and match_addr < (
                        var_addr + byte_size):
                    if verbose:
                        print 'match'
                    return var
    return None


def find_frame_for_stack_address(process, addr):
    closest_delta = sys.maxsize
    closest_frame = None
    # print 'find_frame_for_stack_address(%#x)' % (addr)
    for thread in process:
        prev_sp = lldb.LLDB_INVALID_ADDRESS
        for frame in thread:
            cfa = frame.GetCFA()
            # print 'frame #%u: cfa = %#x' % (frame.GetFrameID(), cfa)
            if addr < cfa:
                delta = cfa - addr
                # print '%#x < %#x, delta = %i' % (addr, cfa, delta)
                if delta < closest_delta:
                    # print 'closest'
                    closest_delta = delta
                    closest_frame = frame
                # else:
                #     print 'delta >= closest_delta'
    return closest_frame


def type_flags_to_description(
        process,
        type_flags,
        ptr_addr,
        ptr_size,
        offset,
        match_addr):
    show_offset = False
    if type_flags == 0 or type_flags & 4:
        type_str = 'free(%#x)' % (ptr_addr,)
    elif type_flags & 2 or type_flags & 1:
        type_str = 'malloc(%6u) -> %#x' % (ptr_size, ptr_addr)
        show_offset = True
    elif type_flags & 8:
        type_str = 'stack'
        frame = find_frame_for_stack_address(process, match_addr)
        if frame:
            type_str += ' in frame #%u of thread #%u: tid %#x' % (frame.GetFrameID(
            ), frame.GetThread().GetIndexID(), frame.GetThread().GetThreadID())
        variables = frame.GetVariables(True, True, True, True)
        matching_var = None
        for var in variables:
            var_addr = var.GetLoadAddress()
            if var_addr != lldb.LLDB_INVALID_ADDRESS:
                # print 'variable "%s" @ %#x (%#x)' % (var.name, var.load_addr,
                # match_addr)
                if var_addr == match_addr:
                    matching_var = var
                    break
                else:
                    byte_size = var.GetType().GetByteSize()
                    if byte_size > 0 and var_addr <= match_addr and match_addr < (
                            var_addr + byte_size):
                        matching_var = var
                        break
        if matching_var:
            type_str += ' in variable at %#x:\n    %s' % (
                matching_var.GetLoadAddress(), matching_var)
    elif type_flags & 16:
        type_str = 'stack (red zone)'
    elif type_flags & 32:
        sb_addr = process.GetTarget().ResolveLoadAddress(ptr_addr + offset)
        type_str = 'segment [%#x - %#x), %s + %u, %s' % (
            ptr_addr, ptr_addr + ptr_size, sb_addr.section.name, sb_addr.offset, sb_addr)
    elif type_flags & 64:
        sb_addr = process.GetTarget().ResolveLoadAddress(ptr_addr + offset)
        type_str = 'vm_region [%#x - %#x), %s + %u, %s' % (
            ptr_addr, ptr_addr + ptr_size, sb_addr.section.name, sb_addr.offset, sb_addr)
    else:
        type_str = '%#x' % (ptr_addr,)
        show_offset = True
    if show_offset and offset != 0:
        type_str += ' + %-6u' % (offset,)
    return type_str


def dump_stack_history_entry(options, result, stack_history_entry, idx):
    address = int(stack_history_entry.address)
    if address:
        type_flags = int(stack_history_entry.type_flags)
        symbolicator = lldb.utils.symbolication.Symbolicator()
        symbolicator.target = lldb.debugger.GetSelectedTarget()
        type_str = type_flags_to_string(type_flags)
        result.AppendMessage(
            'stack[%u]: addr = 0x%x, type=%s, frames:' %
            (idx, address, type_str))
        frame_idx = 0
        idx = 0
        pc = int(stack_history_entry.frames[idx])
        while pc != 0:
            if pc >= 0x1000:
                frames = symbolicator.symbolicate(pc)
                if frames:
                    for frame in frames:
                        result.AppendMessage(
                            '     [%u] %s' %
                            (frame_idx, frame))
                        frame_idx += 1
                else:
                    result.AppendMessage('     [%u] 0x%x' % (frame_idx, pc))
                    frame_idx += 1
                idx = idx + 1
                pc = int(stack_history_entry.frames[idx])
            else:
                pc = 0
        if idx >= options.max_frames:
            result.AppendMessage(
                'warning: the max number of stack frames (%u) was reached, use the "--max-frames=<COUNT>" option to see more frames' %
                (options.max_frames))

        result.AppendMessage('')


def dump_stack_history_entries(options, result, addr, history):
    # malloc_stack_entry *get_stack_history_for_address (const void * addr)
    expr_prefix = '''
typedef int kern_return_t;
typedef struct $malloc_stack_entry {
    uint64_t address;
    uint64_t argument;
    uint32_t type_flags;
    uint32_t num_frames;
    uint64_t frames[512];
    kern_return_t err;
} $malloc_stack_entry;
'''
    single_expr = '''
#define MAX_FRAMES %u
typedef unsigned task_t;
$malloc_stack_entry stack;
stack.address = 0x%x;
stack.type_flags = 2;
stack.num_frames = 0;
stack.frames[0] = 0;
uint32_t max_stack_frames = MAX_FRAMES;
stack.err = (kern_return_t)__mach_stack_logging_get_frames (
    (task_t)mach_task_self(),
    stack.address,
    &stack.frames[0],
    max_stack_frames,
    &stack.num_frames);
if (stack.num_frames < MAX_FRAMES)
    stack.frames[stack.num_frames] = 0;
else
    stack.frames[MAX_FRAMES-1] = 0;
stack''' % (options.max_frames, addr)

    history_expr = '''
typedef int kern_return_t;
typedef unsigned task_t;
#define MAX_FRAMES %u
#define MAX_HISTORY %u
typedef struct mach_stack_logging_record_t {
	uint32_t type_flags;
	uint64_t stack_identifier;
	uint64_t argument;
	uint64_t address;
} mach_stack_logging_record_t;
typedef void (*enumerate_callback_t)(mach_stack_logging_record_t, void *);
typedef struct malloc_stack_entry {
    uint64_t address;
    uint64_t argument;
    uint32_t type_flags;
    uint32_t num_frames;
    uint64_t frames[MAX_FRAMES];
    kern_return_t frames_err;
} malloc_stack_entry;
typedef struct $malloc_stack_history {
    task_t task;
    unsigned idx;
    malloc_stack_entry entries[MAX_HISTORY];
} $malloc_stack_history;
$malloc_stack_history lldb_info = { (task_t)mach_task_self(), 0 };
uint32_t max_stack_frames = MAX_FRAMES;
enumerate_callback_t callback = [] (mach_stack_logging_record_t stack_record, void *baton) -> void {
    $malloc_stack_history *lldb_info = ($malloc_stack_history *)baton;
    if (lldb_info->idx < MAX_HISTORY) {
        malloc_stack_entry *stack_entry = &(lldb_info->entries[lldb_info->idx]);
        stack_entry->address = stack_record.address;
        stack_entry->type_flags = stack_record.type_flags;
        stack_entry->argument = stack_record.argument;
        stack_entry->num_frames = 0;
        stack_entry->frames[0] = 0;
        stack_entry->frames_err = (kern_return_t)__mach_stack_logging_frames_for_uniqued_stack (
            lldb_info->task,
            stack_record.stack_identifier,
            stack_entry->frames,
            (uint32_t)MAX_FRAMES,
            &stack_entry->num_frames);
        // Terminate the frames with zero if there is room
        if (stack_entry->num_frames < MAX_FRAMES)
            stack_entry->frames[stack_entry->num_frames] = 0;
    }
    ++lldb_info->idx;
};
(kern_return_t)__mach_stack_logging_enumerate_records (lldb_info.task, (uint64_t)0x%x, callback, &lldb_info);
lldb_info''' % (options.max_frames, options.max_history, addr)

    frame = lldb.debugger.GetSelectedTarget().GetProcess(
    ).GetSelectedThread().GetSelectedFrame()
    if history:
        expr = history_expr
    else:
        expr = single_expr
    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(True)
    expr_options.SetTimeoutInMicroSeconds(5 * 1000 * 1000)  # 5 second timeout
    expr_options.SetTryAllThreads(True)
    expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
    expr_options.SetPrefix(expr_prefix)
    expr_sbvalue = frame.EvaluateExpression(expr, expr_options)
    if options.verbose:
        print "expression:"
        print expr
        print "expression result:"
        print expr_sbvalue
    if expr_sbvalue.error.Success():
        if history:
            malloc_stack_history = lldb.value(expr_sbvalue)
            num_stacks = int(malloc_stack_history.idx)
            if num_stacks <= options.max_history:
                i_max = num_stacks
            else:
                i_max = options.max_history
            for i in range(i_max):
                stack_history_entry = malloc_stack_history.entries[i]
                dump_stack_history_entry(
                    options, result, stack_history_entry, i)
            if num_stacks > options.max_history:
                result.AppendMessage(
                    'warning: the max number of stacks (%u) was reached, use the "--max-history=%u" option to see all of the stacks' %
                    (options.max_history, num_stacks))
        else:
            stack_history_entry = lldb.value(expr_sbvalue)
            dump_stack_history_entry(options, result, stack_history_entry, 0)

    else:
        result.AppendMessage(
            'error: expression failed "%s" => %s' %
            (expr, expr_sbvalue.error))


def display_match_results(
        process,
        result,
        options,
        arg_str_description,
        expr,
        print_no_matches,
        expr_prefix=None):
    frame = lldb.debugger.GetSelectedTarget().GetProcess(
    ).GetSelectedThread().GetSelectedFrame()
    if not frame:
        result.AppendMessage('error: invalid frame')
        return 0
    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(True)
    expr_options.SetFetchDynamicValue(lldb.eNoDynamicValues)
    expr_options.SetTimeoutInMicroSeconds(
        30 * 1000 * 1000)  # 30 second timeout
    expr_options.SetTryAllThreads(False)
    expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
    if expr_prefix:
        expr_options.SetPrefix(expr_prefix)
    expr_sbvalue = frame.EvaluateExpression(expr, expr_options)
    if options.verbose:
        print "expression:"
        print expr
        print "expression result:"
        print expr_sbvalue
    if expr_sbvalue.error.Success():
        match_value = lldb.value(expr_sbvalue)
        i = 0
        match_idx = 0
        while True:
            print_entry = True
            match_entry = match_value[i]
            i += 1
            if i > options.max_matches:
                result.AppendMessage(
                    'warning: the max number of matches (%u) was reached, use the --max-matches option to get more results' %
                    (options.max_matches))
                break
            malloc_addr = match_entry.addr.sbvalue.unsigned
            if malloc_addr == 0:
                break
            malloc_size = int(match_entry.size)
            offset = int(match_entry.offset)

            if options.offset >= 0 and options.offset != offset:
                print_entry = False
            else:
                match_addr = malloc_addr + offset
                type_flags = int(match_entry.type)
                #result.AppendMessage (hex(malloc_addr + offset))
                if type_flags == 64:
                    search_stack_old = options.search_stack
                    search_segments_old = options.search_segments
                    search_heap_old = options.search_heap
                    search_vm_regions = options.search_vm_regions
                    options.search_stack = True
                    options.search_segments = True
                    options.search_heap = True
                    options.search_vm_regions = False
                    if malloc_info_impl(lldb.debugger, result, options, [
                                        hex(malloc_addr + offset)]):
                        print_entry = False
                    options.search_stack = search_stack_old
                    options.search_segments = search_segments_old
                    options.search_heap = search_heap_old
                    options.search_vm_regions = search_vm_regions
                if print_entry:
                    description = '%#16.16x: %s' % (match_addr, type_flags_to_description(
                        process, type_flags, malloc_addr, malloc_size, offset, match_addr))
                    if options.show_size:
                        description += ' <%5u>' % (malloc_size)
                    if options.show_range:
                        description += ' [%#x - %#x)' % (
                            malloc_addr, malloc_addr + malloc_size)
                    derefed_dynamic_value = None
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(
                        lldb.eDynamicCanRunTarget)
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            process = expr_sbvalue.GetProcess()
                            target = expr_sbvalue.GetTarget()
                            data = bytearray(
                                process.ReadMemory(
                                    malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                ptr_size = target.addr_size
                                thread = process.ReadUnsignedFromMemory(
                                    malloc_addr + 16 + ptr_size, ptr_size, error)
                                #   4 bytes  0xa1a1a1a1
                                #  12 bytes  'AUTORELEASE!'
                                # ptr bytes  autorelease insertion point
                                # ptr bytes  pthread_t
                                # ptr bytes  next colder page
                                # ptr bytes  next hotter page
                                #   4 bytes  this page's depth in the list
                                #   4 bytes  high-water mark
                                description += ' AUTORELEASE! for pthread_t %#x' % (
                                    thread)
                        #     else:
                        #         description += 'malloc(%u)' % (malloc_size)
                        # else:
                        #     description += 'malloc(%u)' % (malloc_size)
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += ' '
                            description += derefed_dynamic_type_name
                            if offset < derefed_dynamic_type_size:
                                member_list = list()
                                get_member_types_for_offset(
                                    derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name:
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(
                                                        member_path):
                                                    print_entry = False
                                        description += '.%s' % (member_path)
                            else:
                                description += '%u bytes after %s' % (
                                    offset - derefed_dynamic_type_size, derefed_dynamic_type_name)
                        else:
                            # strip the "*" from the end of the name since we
                            # were unable to dereference this
                            description += dynamic_value.type.name[0:-1]
            if print_entry:
                match_idx += 1
                result_output = ''
                if description:
                    result_output += description
                    if options.print_type and derefed_dynamic_value:
                        result_output += ' %s' % (derefed_dynamic_value)
                    if options.print_object_description and dynamic_value:
                        desc = dynamic_value.GetObjectDescription()
                        if desc:
                            result_output += '\n%s' % (desc)
                if result_output:
                    result.AppendMessage(result_output)
                if options.memory:
                    cmd_result = lldb.SBCommandReturnObject()
                    if options.format is None:
                        memory_command = "memory read --force 0x%x 0x%x" % (
                            malloc_addr, malloc_addr + malloc_size)
                    else:
                        memory_command = "memory read --force -f %s 0x%x 0x%x" % (
                            options.format, malloc_addr, malloc_addr + malloc_size)
                    if options.verbose:
                        result.AppendMessage(memory_command)
                    lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
                    result.AppendMessage(cmd_result.GetOutput())
                if options.stack_history:
                    dump_stack_history_entries(options, result, malloc_addr, 1)
                elif options.stack:
                    dump_stack_history_entries(options, result, malloc_addr, 0)
        return i
    else:
        result.AppendMessage(str(expr_sbvalue.error))
    return 0


def get_ptr_refs_options():
    usage = "usage: %prog [options] <EXPR> [EXPR ...]"
    description = '''Searches all allocations on the heap for pointer values on
darwin user space programs. Any matches that were found will dump the malloc
blocks that contain the pointers and might be able to print what kind of
objects the pointers are contained in using dynamic type information in the
program.'''
    parser = optparse.OptionParser(
        description=description,
        prog='ptr_refs',
        usage=usage)
    add_common_options(parser)
    return parser


def find_variable(debugger, command, result, dict):
    usage = "usage: %prog [options] <ADDR> [ADDR ...]"
    description = '''Searches for a local variable in all frames that contains a hex ADDR.'''
    command_args = shlex.split(command)
    parser = optparse.OptionParser(
        description=description,
        prog='find_variable',
        usage=usage)
    parser.add_option(
        '-v',
        '--verbose',
        action='store_true',
        dest='verbose',
        help='display verbose debug info',
        default=False)
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    process = debugger.GetSelectedTarget().GetProcess()
    if not process:
        result.AppendMessage('error: invalid process')
        return

    for arg in args:
        var_addr = int(arg, 16)
        print >>result, "Finding a variable with address %#x..." % (var_addr)
        done = False
        for thread in process:
            for frame in thread:
                var = find_variable_containing_address(
                    options.verbose, frame, var_addr)
                if var:
                    print var
                    done = True
                    break
            if done:
                break


def ptr_refs(debugger, command, result, dict):
    command_args = shlex.split(command)
    parser = get_ptr_refs_options()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    process = debugger.GetSelectedTarget().GetProcess()
    if not process:
        result.AppendMessage('error: invalid process')
        return
    frame = process.GetSelectedThread().GetSelectedFrame()
    if not frame:
        result.AppendMessage('error: invalid frame')
        return

    options.type = 'pointer'
    if options.format is None:
        options.format = "A"  # 'A' is "address" format

    if args:
        # When we initialize the expression, we must define any types that
        # we will need when looking at every allocation. We must also define
        # a type named callback_baton_t and make an instance named "baton"
        # and initialize it how ever we want to. The address of "baton" will
        # be passed into our range callback. callback_baton_t must contain
        # a member named "callback" whose type is "range_callback_t". This
        # will be used by our zone callbacks to call the range callback for
        # each malloc range.
        expr_prefix = '''
struct $malloc_match {
    void *addr;
    uintptr_t size;
    uintptr_t offset;
    uintptr_t type;
};
'''
        user_init_code_format = '''
#define MAX_MATCHES %u
typedef struct callback_baton_t {
    range_callback_t callback;
    unsigned num_matches;
    $malloc_match matches[MAX_MATCHES];
    void *ptr;
} callback_baton_t;
range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
    callback_baton_t *lldb_info = (callback_baton_t *)baton;
    typedef void* T;
    const unsigned size = sizeof(T);
    T *array = (T*)ptr_addr;
    for (unsigned idx = 0; ((idx + 1) * sizeof(T)) <= ptr_size; ++idx) {
        if (array[idx] == lldb_info->ptr) {
            if (lldb_info->num_matches < MAX_MATCHES) {
                lldb_info->matches[lldb_info->num_matches].addr = (void*)ptr_addr;
                lldb_info->matches[lldb_info->num_matches].size = ptr_size;
                lldb_info->matches[lldb_info->num_matches].offset = idx*sizeof(T);
                lldb_info->matches[lldb_info->num_matches].type = type;
                ++lldb_info->num_matches;
            }
        }
    }
};
callback_baton_t baton = { range_callback, 0, {0}, (void *)%s };
'''
        # We must also define a snippet of code to be run that returns
        # the result of the expression we run.
        # Here we return NULL if our pointer was not found in any malloc blocks,
        # and we return the address of the matches array so we can then access
        # the matching results
        user_return_code = '''if (baton.num_matches < MAX_MATCHES)
    baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
baton.matches'''
        # Iterate through all of our pointer expressions and display the
        # results
        for ptr_expr in args:
            user_init_code = user_init_code_format % (
                options.max_matches, ptr_expr)
            expr = get_iterate_memory_expr(
                options, process, user_init_code, user_return_code)
            arg_str_description = 'malloc block containing pointer %s' % ptr_expr
            display_match_results(
                process,
                result,
                options,
                arg_str_description,
                expr,
                True,
                expr_prefix)
    else:
        result.AppendMessage('error: no pointer arguments were given')


def get_cstr_refs_options():
    usage = "usage: %prog [options] <CSTR> [CSTR ...]"
    description = '''Searches all allocations on the heap for C string values on
darwin user space programs. Any matches that were found will dump the malloc
blocks that contain the C strings and might be able to print what kind of
objects the pointers are contained in using dynamic type information in the
program.'''
    parser = optparse.OptionParser(
        description=description,
        prog='cstr_refs',
        usage=usage)
    add_common_options(parser)
    return parser


def cstr_refs(debugger, command, result, dict):
    command_args = shlex.split(command)
    parser = get_cstr_refs_options()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    process = debugger.GetSelectedTarget().GetProcess()
    if not process:
        result.AppendMessage('error: invalid process')
        return
    frame = process.GetSelectedThread().GetSelectedFrame()
    if not frame:
        result.AppendMessage('error: invalid frame')
        return

    options.type = 'cstr'
    if options.format is None:
        options.format = "Y"  # 'Y' is "bytes with ASCII" format

    if args:
        # When we initialize the expression, we must define any types that
        # we will need when looking at every allocation. We must also define
        # a type named callback_baton_t and make an instance named "baton"
        # and initialize it how ever we want to. The address of "baton" will
        # be passed into our range callback. callback_baton_t must contain
        # a member named "callback" whose type is "range_callback_t". This
        # will be used by our zone callbacks to call the range callback for
        # each malloc range.
        expr_prefix = '''
struct $malloc_match {
    void *addr;
    uintptr_t size;
    uintptr_t offset;
    uintptr_t type;
};
'''
        user_init_code_format = '''
#define MAX_MATCHES %u
typedef struct callback_baton_t {
    range_callback_t callback;
    unsigned num_matches;
    $malloc_match matches[MAX_MATCHES];
    const char *cstr;
    unsigned cstr_len;
} callback_baton_t;
range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
    callback_baton_t *lldb_info = (callback_baton_t *)baton;
    if (lldb_info->cstr_len < ptr_size) {
        const char *begin = (const char *)ptr_addr;
        const char *end = begin + ptr_size - lldb_info->cstr_len;
        for (const char *s = begin; s < end; ++s) {
            if ((int)memcmp(s, lldb_info->cstr, lldb_info->cstr_len) == 0) {
                if (lldb_info->num_matches < MAX_MATCHES) {
                    lldb_info->matches[lldb_info->num_matches].addr = (void*)ptr_addr;
                    lldb_info->matches[lldb_info->num_matches].size = ptr_size;
                    lldb_info->matches[lldb_info->num_matches].offset = s - begin;
                    lldb_info->matches[lldb_info->num_matches].type = type;
                    ++lldb_info->num_matches;
                }
            }
        }
    }
};
const char *cstr = "%s";
callback_baton_t baton = { range_callback, 0, {0}, cstr, (unsigned)strlen(cstr) };'''
        # We must also define a snippet of code to be run that returns
        # the result of the expression we run.
        # Here we return NULL if our pointer was not found in any malloc blocks,
        # and we return the address of the matches array so we can then access
        # the matching results
        user_return_code = '''if (baton.num_matches < MAX_MATCHES)
    baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
baton.matches'''
        # Iterate through all of our pointer expressions and display the
        # results
        for cstr in args:
            user_init_code = user_init_code_format % (
                options.max_matches, cstr)
            expr = get_iterate_memory_expr(
                options, process, user_init_code, user_return_code)
            arg_str_description = 'malloc block containing "%s"' % cstr
            display_match_results(
                process,
                result,
                options,
                arg_str_description,
                expr,
                True,
                expr_prefix)
    else:
        result.AppendMessage(
            'error: command takes one or more C string arguments')


def get_malloc_info_options():
    usage = "usage: %prog [options] <EXPR> [EXPR ...]"
    description = '''Searches the heap a malloc block that contains the addresses
specified as one or more address expressions. Any matches that were found will
dump the malloc blocks that match or contain the specified address. The matching
blocks might be able to show what kind of objects they are using dynamic type
information in the program.'''
    parser = optparse.OptionParser(
        description=description,
        prog='malloc_info',
        usage=usage)
    add_common_options(parser)
    return parser


def malloc_info(debugger, command, result, dict):
    command_args = shlex.split(command)
    parser = get_malloc_info_options()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    malloc_info_impl(debugger, result, options, args)


def malloc_info_impl(debugger, result, options, args):
    # We are specifically looking for something on the heap only
    options.type = 'malloc_info'

    process = debugger.GetSelectedTarget().GetProcess()
    if not process:
        result.AppendMessage('error: invalid process')
        return
    frame = process.GetSelectedThread().GetSelectedFrame()
    if not frame:
        result.AppendMessage('error: invalid frame')
        return
    expr_prefix = '''
struct $malloc_match {
    void *addr;
    uintptr_t size;
    uintptr_t offset;
    uintptr_t type;
};
'''

    user_init_code_format = '''
typedef struct callback_baton_t {
    range_callback_t callback;
    unsigned num_matches;
    $malloc_match matches[2]; // Two items so they can be NULL terminated
    void *ptr;
} callback_baton_t;
range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
    callback_baton_t *lldb_info = (callback_baton_t *)baton;
    if (lldb_info->num_matches == 0) {
        uint8_t *p = (uint8_t *)lldb_info->ptr;
        uint8_t *lo = (uint8_t *)ptr_addr;
        uint8_t *hi = lo + ptr_size;
        if (lo <= p && p < hi) {
            lldb_info->matches[lldb_info->num_matches].addr = (void*)ptr_addr;
            lldb_info->matches[lldb_info->num_matches].size = ptr_size;
            lldb_info->matches[lldb_info->num_matches].offset = p - lo;
            lldb_info->matches[lldb_info->num_matches].type = type;
            lldb_info->num_matches = 1;
        }
    }
};
callback_baton_t baton = { range_callback, 0, {0}, (void *)%s };
baton.matches[0].addr = 0;
baton.matches[1].addr = 0;'''
    if args:
        total_matches = 0
        for ptr_expr in args:
            user_init_code = user_init_code_format % (ptr_expr)
            expr = get_iterate_memory_expr(
                options, process, user_init_code, 'baton.matches')
            arg_str_description = 'malloc block that contains %s' % ptr_expr
            total_matches += display_match_results(
                process, result, options, arg_str_description, expr, True, expr_prefix)
        return total_matches
    else:
        result.AppendMessage(
            'error: command takes one or more pointer expressions')
        return 0


def get_thread_stack_ranges_struct(process):
    '''Create code that defines a structure that represents threads stack bounds
    for all  threads. It returns a static sized array initialized with all of
    the tid, base, size structs for all the threads.'''
    stack_dicts = list()
    if process:
        i = 0
        for thread in process:
            min_sp = thread.frame[0].sp
            max_sp = min_sp
            for frame in thread.frames:
                sp = frame.sp
                if sp < min_sp:
                    min_sp = sp
                if sp > max_sp:
                    max_sp = sp
            if min_sp < max_sp:
                stack_dicts.append({'tid': thread.GetThreadID(
                ), 'base': min_sp, 'size': max_sp - min_sp, 'index': i})
                i += 1
    stack_dicts_len = len(stack_dicts)
    if stack_dicts_len > 0:
        result = '''
#define NUM_STACKS %u
#define STACK_RED_ZONE_SIZE %u
typedef struct thread_stack_t { uint64_t tid, base, size; } thread_stack_t;
thread_stack_t stacks[NUM_STACKS];''' % (stack_dicts_len, process.target.GetStackRedZoneSize())
        for stack_dict in stack_dicts:
            result += '''
stacks[%(index)u].tid  = 0x%(tid)x;
stacks[%(index)u].base = 0x%(base)x;
stacks[%(index)u].size = 0x%(size)x;''' % stack_dict
        return result
    else:
        return ''


def get_sections_ranges_struct(process):
    '''Create code that defines a structure that represents all segments that
    can contain data for all images in "target". It returns a static sized
    array initialized with all of base, size structs for all the threads.'''
    target = process.target
    segment_dicts = list()
    for (module_idx, module) in enumerate(target.modules):
        for sect_idx in range(module.GetNumSections()):
            section = module.GetSectionAtIndex(sect_idx)
            if not section:
                break
            name = section.name
            if name != '__TEXT' and name != '__LINKEDIT' and name != '__PAGEZERO':
                base = section.GetLoadAddress(target)
                size = section.GetByteSize()
                if base != lldb.LLDB_INVALID_ADDRESS and size > 0:
                    segment_dicts.append({'base': base, 'size': size})
    segment_dicts_len = len(segment_dicts)
    if segment_dicts_len > 0:
        result = '''
#define NUM_SEGMENTS %u
typedef struct segment_range_t { uint64_t base; uint32_t size; } segment_range_t;
segment_range_t segments[NUM_SEGMENTS];''' % (segment_dicts_len,)
        for (idx, segment_dict) in enumerate(segment_dicts):
            segment_dict['index'] = idx
            result += '''
segments[%(index)u].base = 0x%(base)x;
segments[%(index)u].size = 0x%(size)x;''' % segment_dict
        return result
    else:
        return ''


def section_ptr_refs(debugger, command, result, dict):
    command_args = shlex.split(command)
    usage = "usage: %prog [options] <EXPR> [EXPR ...]"
    description = '''Searches section contents for pointer values in darwin user space programs.'''
    parser = optparse.OptionParser(
        description=description,
        prog='section_ptr_refs',
        usage=usage)
    add_common_options(parser)
    parser.add_option(
        '--section',
        action='append',
        type='string',
        dest='section_names',
        help='section name to search',
        default=list())
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    options.type = 'pointer'

    sections = list()
    section_modules = list()
    if not options.section_names:
        result.AppendMessage(
            'error: at least one section must be specified with the --section option')
        return

    target = debugger.GetSelectedTarget()
    for module in target.modules:
        for section_name in options.section_names:
            section = module.section[section_name]
            if section:
                sections.append(section)
                section_modules.append(module)
    if sections:
        dylid_load_err = load_dylib()
        if dylid_load_err:
            result.AppendMessage(dylid_load_err)
            return
        frame = target.GetProcess().GetSelectedThread().GetSelectedFrame()
        for expr_str in args:
            for (idx, section) in enumerate(sections):
                expr = 'find_pointer_in_memory(0x%xllu, %ullu, (void *)%s)' % (
                    section.addr.load_addr, section.size, expr_str)
                arg_str_description = 'section %s.%s containing "%s"' % (
                    section_modules[idx].file.fullpath, section.name, expr_str)
                num_matches = display_match_results(
                    target.GetProcess(), result, options, arg_str_description, expr, False)
                if num_matches:
                    if num_matches < options.max_matches:
                        options.max_matches = options.max_matches - num_matches
                    else:
                        options.max_matches = 0
                if options.max_matches == 0:
                    return
    else:
        result.AppendMessage(
            'error: no sections were found that match any of %s' %
            (', '.join(
                options.section_names)))


def get_objc_refs_options():
    usage = "usage: %prog [options] <CLASS> [CLASS ...]"
    description = '''Searches all allocations on the heap for instances of
objective C classes, or any classes that inherit from the specified classes
in darwin user space programs. Any matches that were found will dump the malloc
blocks that contain the C strings and might be able to print what kind of
objects the pointers are contained in using dynamic type information in the
program.'''
    parser = optparse.OptionParser(
        description=description,
        prog='objc_refs',
        usage=usage)
    add_common_options(parser)
    return parser


def objc_refs(debugger, command, result, dict):
    command_args = shlex.split(command)
    parser = get_objc_refs_options()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return

    process = debugger.GetSelectedTarget().GetProcess()
    if not process:
        result.AppendMessage('error: invalid process')
        return
    frame = process.GetSelectedThread().GetSelectedFrame()
    if not frame:
        result.AppendMessage('error: invalid frame')
        return

    options.type = 'isa'
    if options.format is None:
        options.format = "A"  # 'A' is "address" format

    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(True)
    expr_options.SetTimeoutInMicroSeconds(
        3 * 1000 * 1000)  # 3 second infinite timeout
    expr_options.SetTryAllThreads(True)
    expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
    num_objc_classes_value = frame.EvaluateExpression(
        "(int)objc_getClassList((void *)0, (int)0)", expr_options)
    if not num_objc_classes_value.error.Success():
        result.AppendMessage('error: %s' %
                             num_objc_classes_value.error.GetCString())
        return

    num_objc_classes = num_objc_classes_value.GetValueAsUnsigned()
    if num_objc_classes == 0:
        result.AppendMessage('error: no objective C classes in program')
        return

    if args:
        # When we initialize the expression, we must define any types that
        # we will need when looking at every allocation. We must also define
        # a type named callback_baton_t and make an instance named "baton"
        # and initialize it how ever we want to. The address of "baton" will
        # be passed into our range callback. callback_baton_t must contain
        # a member named "callback" whose type is "range_callback_t". This
        # will be used by our zone callbacks to call the range callback for
        # each malloc range.
        expr_prefix = '''
struct $malloc_match {
    void *addr;
    uintptr_t size;
    uintptr_t offset;
    uintptr_t type;
};
'''

        user_init_code_format = '''
#define MAX_MATCHES %u
typedef int (*compare_callback_t)(const void *a, const void *b);
typedef struct callback_baton_t {
    range_callback_t callback;
    compare_callback_t compare_callback;
    unsigned num_matches;
    $malloc_match matches[MAX_MATCHES];
    void *isa;
    Class classes[%u];
} callback_baton_t;
compare_callback_t compare_callback = [](const void *a, const void *b) -> int {
     Class a_ptr = *(Class *)a;
     Class b_ptr = *(Class *)b;
     if (a_ptr < b_ptr) return -1;
     if (a_ptr > b_ptr) return +1;
     return 0;
};
typedef Class (*class_getSuperclass_type)(void *isa);
range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
    class_getSuperclass_type class_getSuperclass_impl = (class_getSuperclass_type)class_getSuperclass;
    callback_baton_t *lldb_info = (callback_baton_t *)baton;
    if (sizeof(Class) <= ptr_size) {
        Class *curr_class_ptr = (Class *)ptr_addr;
        Class *matching_class_ptr = (Class *)bsearch (curr_class_ptr,
                                                      (const void *)lldb_info->classes,
                                                      sizeof(lldb_info->classes)/sizeof(Class),
                                                      sizeof(Class),
                                                      lldb_info->compare_callback);
        if (matching_class_ptr) {
            bool match = false;
            if (lldb_info->isa) {
                Class isa = *curr_class_ptr;
                if (lldb_info->isa == isa)
                    match = true;
                else { // if (lldb_info->objc.match_superclasses) {
                    Class super = class_getSuperclass_impl(isa);
                    while (super) {
                        if (super == lldb_info->isa) {
                            match = true;
                            break;
                        }
                        super = class_getSuperclass_impl(super);
                    }
                }
            }
            else
                match = true;
            if (match) {
                if (lldb_info->num_matches < MAX_MATCHES) {
                    lldb_info->matches[lldb_info->num_matches].addr = (void*)ptr_addr;
                    lldb_info->matches[lldb_info->num_matches].size = ptr_size;
                    lldb_info->matches[lldb_info->num_matches].offset = 0;
                    lldb_info->matches[lldb_info->num_matches].type = type;
                    ++lldb_info->num_matches;
                }
            }
        }
    }
};
callback_baton_t baton = { range_callback, compare_callback, 0, {0}, (void *)0x%x, {0} };
int nc = (int)objc_getClassList(baton.classes, sizeof(baton.classes)/sizeof(Class));
(void)qsort (baton.classes, sizeof(baton.classes)/sizeof(Class), sizeof(Class), compare_callback);'''
        # We must also define a snippet of code to be run that returns
        # the result of the expression we run.
        # Here we return NULL if our pointer was not found in any malloc blocks,
        # and we return the address of the matches array so we can then access
        # the matching results
        user_return_code = '''if (baton.num_matches < MAX_MATCHES)
    baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
        baton.matches'''
        # Iterate through all of our ObjC class name arguments
        for class_name in args:
            addr_expr_str = "(void *)[%s class]" % class_name
            expr_options = lldb.SBExpressionOptions()
            expr_options.SetIgnoreBreakpoints(True)
            expr_options.SetTimeoutInMicroSeconds(
                1 * 1000 * 1000)  # 1 second timeout
            expr_options.SetTryAllThreads(True)
            expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
            expr_sbvalue = frame.EvaluateExpression(
                addr_expr_str, expr_options)
            if expr_sbvalue.error.Success():
                isa = expr_sbvalue.unsigned
                if isa:
                    options.type = 'isa'
                    result.AppendMessage(
                        'Searching for all instances of classes or subclasses of "%s" (isa=0x%x)' %
                        (class_name, isa))
                    user_init_code = user_init_code_format % (
                        options.max_matches, num_objc_classes, isa)
                    expr = get_iterate_memory_expr(
                        options, process, user_init_code, user_return_code)
                    arg_str_description = 'objective C classes with isa 0x%x' % isa
                    display_match_results(
                        process,
                        result,
                        options,
                        arg_str_description,
                        expr,
                        True,
                        expr_prefix)
                else:
                    result.AppendMessage(
                        'error: Can\'t find isa for an ObjC class named "%s"' %
                        (class_name))
            else:
                result.AppendMessage(
                    'error: expression error for "%s": %s' %
                    (addr_expr_str, expr_sbvalue.error))
    else:
        result.AppendMessage(
            'error: command takes one or more C string arguments')

if __name__ == '__main__':
    lldb.debugger = lldb.SBDebugger.Create()

# Make the options so we can generate the help text for the new LLDB
# command line command prior to registering it with LLDB below. This way
# if clients in LLDB type "help malloc_info", they will see the exact same
# output as typing "malloc_info --help".
ptr_refs.__doc__ = get_ptr_refs_options().format_help()
cstr_refs.__doc__ = get_cstr_refs_options().format_help()
malloc_info.__doc__ = get_malloc_info_options().format_help()
objc_refs.__doc__ = get_objc_refs_options().format_help()
lldb.debugger.HandleCommand(
    'command script add -f %s.ptr_refs ptr_refs' %
    __name__)
lldb.debugger.HandleCommand(
    'command script add -f %s.cstr_refs cstr_refs' %
    __name__)
lldb.debugger.HandleCommand(
    'command script add -f %s.malloc_info malloc_info' %
    __name__)
lldb.debugger.HandleCommand(
    'command script add -f %s.find_variable find_variable' %
    __name__)
# lldb.debugger.HandleCommand('command script add -f %s.heap heap' % package_name)
# lldb.debugger.HandleCommand('command script add -f %s.section_ptr_refs section_ptr_refs' % package_name)
# lldb.debugger.HandleCommand('command script add -f %s.stack_ptr_refs stack_ptr_refs' % package_name)
lldb.debugger.HandleCommand(
    'command script add -f %s.objc_refs objc_refs' %
    __name__)
print '"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.'
