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 frame_info = {} 20 for thread in lldb.process: 21 last_frame = None 22 print "thread %u" % (thread.id) 23 for frame in thread.frames: 24 if last_frame: 25 frame_size = 0 26 if frame.idx == 1: 27 if frame.fp == last_frame.fp: 28 # No frame one the first frame (might be right at the entry point) 29 first_frame_size = 0 30 frame_size = frame.fp - frame.sp 31 else: 32 # First frame that has a valid size 33 first_frame_size = last_frame.fp - last_frame.sp 34 print "<%#7x> %s" % (first_frame_size, last_frame) 35 if first_frame_size: 36 name = last_frame.name 37 if name not in frame_info: 38 frame_info[name] = first_frame_size 39 else: 40 frame_info[name] += first_frame_size 41 else: 42 # Second or higher frame 43 frame_size = frame.fp - last_frame.fp 44 print "<%#7x> %s" % (frame_size, frame) 45 if frame_size > 0: 46 name = frame.name 47 if name not in frame_info: 48 frame_info[name] = frame_size 49 else: 50 frame_info[name] += frame_size 51 last_frame = frame 52 print frame_info 53 54 55lldb.debugger.HandleCommand("command script add -f stacks.stack_frames stack_frames") 56print "A new command called 'stack_frames' was added, type 'stack_frames --help' for more information."