diff options
author | Greg Clayton <gclayton@apple.com> | 2012-04-21 00:11:26 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-04-21 00:11:26 +0000 |
commit | b403a15dedec108f9435fb55e00d4548372029bd (patch) | |
tree | 61648eec1233497c8dac46e2292a15c23d4aba95 /lldb/examples | |
parent | 34d3a38a9caf50b4893155cbcb161d1137554c3d (diff) | |
download | bcm5719-llvm-b403a15dedec108f9435fb55e00d4548372029bd.tar.gz bcm5719-llvm-b403a15dedec108f9435fb55e00d4548372029bd.zip |
Added code to automatically load the libheap.dylib when ptr_refs, cstr_refs or malloc_info are called. If MallocStackLogging is enabled, then you can now use --stack to dump the backtrace of the code that allocated each malloc block.
llvm-svn: 155262
Diffstat (limited to 'lldb/examples')
-rw-r--r-- | lldb/examples/darwin/heap_find/heap.py | 80 | ||||
-rw-r--r-- | lldb/examples/darwin/heap_find/heap_find.cpp | 3 |
2 files changed, 81 insertions, 2 deletions
diff --git a/lldb/examples/darwin/heap_find/heap.py b/lldb/examples/darwin/heap_find/heap.py index f4020edc049..da36495c2ac 100644 --- a/lldb/examples/darwin/heap_find/heap.py +++ b/lldb/examples/darwin/heap_find/heap.py @@ -20,14 +20,57 @@ import commands import optparse import os import shlex +import symbolication # from lldb/examples/python/symbolication.py +def load_dylib(): + if lldb.target: + python_module_directory = os.path.dirname(__file__) + libheap_dylib_path = python_module_directory + '/libheap.dylib' + if not os.path.exists(libheap_dylib_path): + make_command = '(cd "%s" ; make)' % python_module_directory + print make_command + print commands.getoutput(make_command) + if os.path.exists(libheap_dylib_path): + libheap_dylib_spec = lldb.SBFileSpec(libheap_dylib_path) + if lldb.target.FindModule(libheap_dylib_spec): + return None # success, 'libheap.dylib' already loaded + if lldb.process: + state = lldb.process.state + if state == lldb.eStateStopped: + (libheap_dylib_path) + error = lldb.SBError() + image_idx = lldb.process.LoadImage(libheap_dylib_spec, error) + if error.Success(): + return None + else: + if error: + return 'error: %s' % error + else: + return 'error: "process load \'%s\'" failed' % libheap_dylib_spec + else: + return 'error: process is not stopped' + else: + return 'error: invalid process' + else: + return 'error: file does not exist "%s"' % libheap_dylib_path + else: + return 'error: invalid target' + + debugger.HandleCommand('process load "%s"' % libheap_dylib_path) + 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('-o', '--po', action='store_true', dest='print_object_description', help='print the object descriptions for any matches', 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('-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) def heap_search(options, arg_str): + dylid_load_err = load_dylib() + if dylid_load_err: + print dylid_load_err + return expr = None arg_str_description = arg_str default_memory_format = "Y" # 'Y' is "bytes with ASCII" format @@ -128,6 +171,41 @@ def heap_search(options, arg_str): memory_command = "memory read -f %s 0x%x 0x%x" % (memory_format, malloc_addr, malloc_addr + malloc_size) lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result) print cmd_result.GetOutput() + if options.stack: + symbolicator = symbolication.Symbolicator() + symbolicator.target = lldb.target + expr_str = "g_stack_frames_count = sizeof(g_stack_frames)/sizeof(uint64_t); (int)__mach_stack_logging_get_frames((unsigned)mach_task_self(), 0x%xull, g_stack_frames, g_stack_frames_count, &g_stack_frames_count)" % (malloc_addr) + #print expr_str + expr = lldb.frame.EvaluateExpression (expr_str); + expr_error = expr.GetError() + if expr_error.Success(): + err = expr.unsigned + if err: + print 'error: __mach_stack_logging_get_frames() returned error %i' % (err) + else: + count_expr = lldb.frame.EvaluateExpression ("g_stack_frames_count") + count = count_expr.unsigned + #print 'g_stack_frames_count is %u' % (count) + if count > 0: + frame_idx = 0 + frames_expr = lldb.value(lldb.frame.EvaluateExpression ("g_stack_frames")) + done = False + for stack_frame_idx in range(count): + if not done: + frame_load_addr = int(frames_expr[stack_frame_idx]) + if frame_load_addr >= 0x1000: + frames = symbolicator.symbolicate(frame_load_addr) + if frames: + for frame in frames: + print '[%3u] %s' % (frame_idx, frame) + frame_idx += 1 + else: + print '[%3u] 0x%x' % (frame_idx, frame_load_addr) + frame_idx += 1 + else: + done = True + else: + print 'error: %s' % (expr_error) else: print '%s %s was not found in any malloc blocks' % (options.type, arg_str) else: @@ -209,8 +287,6 @@ def malloc_info(debugger, command, result, dict): def __lldb_init_module (debugger, dict): # This initializer is being run from LLDB in the embedded command interpreter # Add any commands contained in this module to LLDB - libheap_dylib_path = os.path.dirname(__file__) + '/libheap.dylib' - debugger.HandleCommand('process load "%s"' % libheap_dylib_path) debugger.HandleCommand('command script add -f heap.ptr_refs ptr_refs') debugger.HandleCommand('command script add -f heap.cstr_refs cstr_refs') debugger.HandleCommand('command script add -f heap.malloc_info malloc_info') diff --git a/lldb/examples/darwin/heap_find/heap_find.cpp b/lldb/examples/darwin/heap_find/heap_find.cpp index 06fa163568e..85c3b7628bc 100644 --- a/lldb/examples/darwin/heap_find/heap_find.cpp +++ b/lldb/examples/darwin/heap_find/heap_find.cpp @@ -73,6 +73,7 @@ #include <stdlib.h> #include <vector> +#define MAX_FRAMES 1024 typedef void range_callback_t (task_t task, void *baton, unsigned type, uint64_t ptr_addr, uint64_t ptr_size); typedef void zone_callback_t (void *info, const malloc_zone_t *zone); @@ -118,6 +119,8 @@ struct malloc_match std::vector<malloc_match> g_matches; const void *g_lookup_addr = 0; +mach_vm_address_t g_stack_frames[MAX_FRAMES]; +uint32_t g_stack_frames_count = 0; //---------------------------------------------------------------------- // task_peek |