[Lldb-commits] [lldb] r156623 - in /lldb/branches/lldb-platform-work: ./ examples/darwin/heap_find/heap.py examples/darwin/heap_find/heap/heap_find.cpp
Johnny Chen
johnny.chen at apple.com
Fri May 11 10:55:54 PDT 2012
Author: johnny
Date: Fri May 11 12:55:53 2012
New Revision: 156623
URL: http://llvm.org/viewvc/llvm-project?rev=156623&view=rev
Log:
Merge changes from ToT trunk.
Modified:
lldb/branches/lldb-platform-work/ (props changed)
lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap.py
lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap/heap_find.cpp
Propchange: lldb/branches/lldb-platform-work/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri May 11 12:55:53 2012
@@ -1 +1 @@
-/lldb/trunk:154223-156596
+/lldb/trunk:154223-156605
Modified: lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap.py?rev=156623&r1=156622&r2=156623&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap.py (original)
+++ lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap.py Fri May 11 12:55:53 2012
@@ -20,6 +20,7 @@
g_libheap_dylib_dir = None
g_libheap_dylib_dict = dict()
+g_verbose = False
def load_dylib():
if lldb.target:
@@ -72,6 +73,9 @@
return 'error: invalid target'
debugger.HandleCommand('process load "%s"' % libheap_dylib_path)
+ if lldb.target.FindModule(libheap_dylib_spec):
+ return None # success, 'libheap.dylib' already loaded
+ return 'error: failed to 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)
@@ -81,17 +85,25 @@
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)
-type_flag_strings = [ 'free', 'generic', 'alloc', 'dealloc' ];
-
def dump_stack_history_entry(stack_history_entry, idx):
address = int(stack_history_entry.address)
if address:
type_flags = int(stack_history_entry.type_flags)
- argument = int(stack_history_entry.argument)
symbolicator = lldb.utils.symbolication.Symbolicator()
symbolicator.target = lldb.target
- global type_flag_strings
- print 'stack_history_entry[%u]: addr = 0x%x, type=%s, arg=%u, frames=' % (idx, address, type_flag_strings[type_flags], argument)
+ type_str = ''
+ if type_flags == 0:
+ type_str = 'free'
+ else:
+ if type_flags & 2:
+ type_str = 'alloc'
+ elif type_flags & 4:
+ type_str = 'free'
+ elif type_flags & 1:
+ type_str = 'generic'
+ else:
+ type_str = hex(type_flags)
+ print 'stack[%u]: addr = 0x%x, type=%s, frames:' % (idx, address, type_str)
frame_idx = 0
idx = 0
pc = int(stack_history_entry.frames[idx])
@@ -100,20 +112,20 @@
frames = symbolicator.symbolicate(pc)
if frames:
for frame in frames:
- print '[%3u] %s' % (frame_idx, frame)
+ print ' [%u] %s' % (frame_idx, frame)
frame_idx += 1
else:
- print '[%3u] 0x%x' % (frame_idx, pc)
+ print ' [%u] 0x%x' % (frame_idx, pc)
frame_idx += 1
idx = idx + 1
pc = int(stack_history_entry.frames[idx])
else:
pc = 0
+ print
-def dump_stack_history_entries(addr):
+def dump_stack_history_entries(addr, history):
# malloc_stack_entry *get_stack_history_for_address (const void * addr)
-
- expr = 'get_stack_history_for_address((void *)0x%x)' % (addr)
+ expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
print 'expr = "%s"' % (expr)
expr_sbvalue = lldb.frame.EvaluateExpression (expr)
if expr_sbvalue.error.Success():
@@ -126,6 +138,10 @@
dump_stack_history_entry(stack_history_entry, idx)
idx = idx + 1
stack_history_entry = expr_value[idx]
+ else:
+ print 'error: expression returned => %s' % (expr_sbvalue)
+ else:
+ print 'error: expression failed "%s" => %s' % (expr, expr_sbvalue.error)
def heap_search(options, arg_str):
@@ -234,42 +250,9 @@
lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
print cmd_result.GetOutput()
if options.stack_history:
- dump_stack_history_entries(malloc_addr)
+ dump_stack_history_entries(malloc_addr, 1)
elif options.stack:
- symbolicator = lldb.utils.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)
+ dump_stack_history_entries(malloc_addr, 0)
else:
print '%s %s was not found in any malloc blocks' % (options.type, arg_str)
else:
@@ -278,7 +261,7 @@
def ptr_refs(debugger, command, result, dict):
command_args = shlex.split(command)
- usage = "usage: %prog [options] <PTR> [PTR ...]"
+ usage = "usage: %prog [options] <EXPR> [EXPR ...]"
description='''Searches the heap for pointer references on darwin user space programs.
Any matches that were found will dump the malloc blocks that contain the pointers
@@ -326,7 +309,7 @@
def malloc_info(debugger, command, result, dict):
command_args = shlex.split(command)
- usage = "usage: %prog [options] <ADDR> [ADDR ...]"
+ usage = "usage: %prog [options] <EXPR> [EXPR ...]"
description='''Searches the heap a malloc block that contains the addresses specified as arguments.
Any matches that were found will dump the malloc blocks that match or contain
@@ -338,16 +321,37 @@
(options, args) = parser.parse_args(command_args)
except:
return
-
options.type = 'addr'
-
if args:
-
for data in args:
heap_search (options, data)
else:
print 'error: no c string arguments were given to search for'
+def malloc_history(debugger, command, result, dict):
+ command_args = shlex.split(command)
+ usage = "usage: %prog [options] <EXPR> [EXPR ...]"
+ description='''Gets the allocation history for an expression whose result is an address.
+
+ Programs should set the MallocStackLoggingNoCompact=1 in the environment to enable stack history. This can be done
+ with "process launch -v MallocStackLoggingNoCompact=1 -- [arg1 ...]"'''
+
+ dylid_load_err = load_dylib()
+ if dylid_load_err:
+ print dylid_load_err
+ else:
+ if command_args:
+ for addr_expr_str in command_args:
+ expr_sbvalue = lldb.frame.EvaluateExpression (addr_expr_str)
+ if expr_sbvalue.error.Success():
+ addr = expr_sbvalue.unsigned
+ if addr != 0:
+ dump_stack_history_entries (addr, 1)
+ else:
+ print 'error: expression error for "%s": %s' % (addr_expr_str, expr_sbvalue.error)
+ else:
+ print 'error: no address expressions were specified'
+
if __name__ == '__main__':
lldb.debugger = lldb.SBDebugger.Create()
@@ -356,7 +360,8 @@
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.ptr_refs ptr_refs')
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.cstr_refs cstr_refs')
lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_info malloc_info')
-print '"ptr_refs", "cstr_refs", and "malloc_info" commands have been installed, use the "--help" options on these commands for detailed help.'
+lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_history malloc_history')
+print '"ptr_refs", "cstr_refs", "malloc_info", and "malloc_history" commands have been installed, use the "--help" options on these commands for detailed help.'
Modified: lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap/heap_find.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap/heap_find.cpp?rev=156623&r1=156622&r2=156623&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap/heap_find.cpp (original)
+++ lldb/branches/lldb-platform-work/examples/darwin/heap_find/heap/heap_find.cpp Fri May 11 12:55:53 2012
@@ -121,7 +121,7 @@
struct malloc_stack_entry
{
- void *address;
+ const void *address;
uint64_t argument;
uint32_t type_flags;
std::vector<uintptr_t> frames;
@@ -132,7 +132,7 @@
const void *g_lookup_addr = 0;
std::vector<malloc_stack_entry> g_malloc_stack_history;
mach_vm_address_t g_stack_frames[MAX_FRAMES];
-uint32_t g_stack_frames_count = 0;
+char g_error_string[PATH_MAX];
//----------------------------------------------------------------------
// task_peek
@@ -273,21 +273,42 @@
}
malloc_stack_entry *
-get_stack_history_for_address (const void * addr)
+get_stack_history_for_address (const void * addr, int history)
{
- // typedef struct {
- // uint32_t type_flags;
- // uint64_t stack_identifier;
- // uint64_t argument;
- // mach_vm_address_t address;
- // } mach_stack_logging_record_t;
std::vector<malloc_stack_entry> empty;
g_malloc_stack_history.swap(empty);
+ if (!stack_logging_enable_logging || (history && !stack_logging_dontcompact))
+ {
+ if (history)
+ strncpy(g_error_string, "error: stack history logging is not enabled, set MallocStackLoggingNoCompact=1 in the environment when launching to enable stack history logging.", sizeof(g_error_string));
+ else
+ strncpy(g_error_string, "error: stack logging is not enabled, set MallocStackLogging=1 in the environment when launching to enable stack logging.", sizeof(g_error_string));
+ return NULL;
+ }
+ kern_return_t err;
task_t task = mach_task_self();
- kern_return_t err = __mach_stack_logging_enumerate_records (task,
- (mach_vm_address_t)addr,
- get_stack_for_address_enumerator,
- &task);
+ if (history)
+ {
+ err = __mach_stack_logging_enumerate_records (task,
+ (mach_vm_address_t)addr,
+ get_stack_for_address_enumerator,
+ &task);
+ }
+ else
+ {
+ uint32_t num_frames = 0;
+ err = __mach_stack_logging_get_frames(task, (mach_vm_address_t)addr, g_stack_frames, MAX_FRAMES, &num_frames);
+ if (err == 0 && num_frames > 0)
+ {
+ g_malloc_stack_history.resize(1);
+ g_malloc_stack_history.back().address = addr;
+ g_malloc_stack_history.back().type_flags = stack_logging_type_alloc;
+ g_malloc_stack_history.back().argument = 0;
+ if (num_frames > 0)
+ g_malloc_stack_history.back().frames.assign(g_stack_frames, g_stack_frames + num_frames);
+ g_malloc_stack_history.back().frames.push_back(0); // Terminate the frames with zero
+ }
+ }
// Append an empty entry
if (g_malloc_stack_history.empty())
return NULL;
More information about the lldb-commits
mailing list