1#!/usr/bin/python 2 3import lldb 4import commands 5import optparse 6import shlex 7 8 9def stack_frames(debugger, command, result, dict): 10 command_args = shlex.split(command) 11 usage = "usage: %prog [options] <PATH> [PATH ...]" 12 description = '''This command will enumerate all stack frames, print the stack size for each, and print an aggregation of which functions have the largest stack frame sizes at the end.''' 13 parser = optparse.OptionParser( 14 description=description, prog='ls', usage=usage) 15 parser.add_option( 16 '-v', 17 '--verbose', 18 action='store_true', 19 dest='verbose', 20 help='display verbose debug info', 21 default=False) 22 try: 23 (options, args) = parser.parse_args(command_args) 24 except: 25 return 26 27 target = debugger.GetSelectedTarget() 28 process = target.GetProcess() 29 30 frame_info = {} 31 for thread in process: 32 last_frame = None 33 print "thread %u" % (thread.id) 34 for frame in thread.frames: 35 if last_frame: 36 frame_size = 0 37 if frame.idx == 1: 38 if frame.fp == last_frame.fp: 39 # No frame one the first frame (might be right at the 40 # entry point) 41 first_frame_size = 0 42 frame_size = frame.fp - frame.sp 43 else: 44 # First frame that has a valid size 45 first_frame_size = last_frame.fp - last_frame.sp 46 print "<%#7x> %s" % (first_frame_size, last_frame) 47 if first_frame_size: 48 name = last_frame.name 49 if name not in frame_info: 50 frame_info[name] = first_frame_size 51 else: 52 frame_info[name] += first_frame_size 53 else: 54 # Second or higher frame 55 frame_size = frame.fp - last_frame.fp 56 print "<%#7x> %s" % (frame_size, frame) 57 if frame_size > 0: 58 name = frame.name 59 if name not in frame_info: 60 frame_info[name] = frame_size 61 else: 62 frame_info[name] += frame_size 63 last_frame = frame 64 print frame_info 65 66 67lldb.debugger.HandleCommand( 68 "command script add -f stacks.stack_frames stack_frames") 69print "A new command called 'stack_frames' was added, type 'stack_frames --help' for more information." 70