#!/usr/bin/env python3

#----------------------------------------------------------------------
# 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, void *, unsigned, uintptr_t, uintptr_t);
'''
    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, vm_address_t, vm_size_t, void **);
typedef void (*vm_range_recorder_t)(task_t, void *, unsigned, vm_range_t *, unsigned);
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;
kern_return_t malloc_get_all_zones(task_t, memory_reader_t, vm_address_t **, unsigned *);
memory_reader_t task_peek = [](task_t, vm_address_t remote_address, vm_size_t, 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_exclusions.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_exclusions',
        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_exclusions:
                                            for ivar_regex in options.ivar_regex_exclusions:
                                                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.')
