#!/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
#----------------------------------------------------------------------

from __future__ import print_function
import lldb
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("Finding a variable with address %#x..." % (var_addr), file=result)
        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.')
