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