1be691f3bSpatrick#!/usr/bin/env python 2061da546Spatrickimport lldb 3061da546Spatrickimport optparse 4061da546Spatrickimport shlex 5061da546Spatrick 6061da546Spatrick 7061da546Spatrickdef stack_frames(debugger, command, result, dict): 8061da546Spatrick command_args = shlex.split(command) 9061da546Spatrick usage = "usage: %prog [options] <PATH> [PATH ...]" 10061da546Spatrick 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.''' 11061da546Spatrick parser = optparse.OptionParser( 12061da546Spatrick description=description, prog='ls', usage=usage) 13061da546Spatrick parser.add_option( 14061da546Spatrick '-v', 15061da546Spatrick '--verbose', 16061da546Spatrick action='store_true', 17061da546Spatrick dest='verbose', 18061da546Spatrick help='display verbose debug info', 19061da546Spatrick default=False) 20061da546Spatrick try: 21061da546Spatrick (options, args) = parser.parse_args(command_args) 22061da546Spatrick except: 23061da546Spatrick return 24061da546Spatrick 25061da546Spatrick target = debugger.GetSelectedTarget() 26061da546Spatrick process = target.GetProcess() 27061da546Spatrick 28061da546Spatrick frame_info = {} 29061da546Spatrick for thread in process: 30061da546Spatrick last_frame = None 31061da546Spatrick print("thread %u" % (thread.id)) 32061da546Spatrick for frame in thread.frames: 33061da546Spatrick if last_frame: 34061da546Spatrick frame_size = 0 35061da546Spatrick if frame.idx == 1: 36061da546Spatrick if frame.fp == last_frame.fp: 37061da546Spatrick # No frame one the first frame (might be right at the 38061da546Spatrick # entry point) 39061da546Spatrick first_frame_size = 0 40061da546Spatrick frame_size = frame.fp - frame.sp 41061da546Spatrick else: 42061da546Spatrick # First frame that has a valid size 43061da546Spatrick first_frame_size = last_frame.fp - last_frame.sp 44061da546Spatrick print("<%#7x> %s" % (first_frame_size, last_frame)) 45061da546Spatrick if first_frame_size: 46061da546Spatrick name = last_frame.name 47061da546Spatrick if name not in frame_info: 48061da546Spatrick frame_info[name] = first_frame_size 49061da546Spatrick else: 50061da546Spatrick frame_info[name] += first_frame_size 51061da546Spatrick else: 52061da546Spatrick # Second or higher frame 53061da546Spatrick frame_size = frame.fp - last_frame.fp 54061da546Spatrick print("<%#7x> %s" % (frame_size, frame)) 55061da546Spatrick if frame_size > 0: 56061da546Spatrick name = frame.name 57061da546Spatrick if name not in frame_info: 58061da546Spatrick frame_info[name] = frame_size 59061da546Spatrick else: 60061da546Spatrick frame_info[name] += frame_size 61061da546Spatrick last_frame = frame 62061da546Spatrick print(frame_info) 63061da546Spatrick 64061da546Spatrick 65*f6aab3d8Srobertdef __lldb_init_module(debugger, internal_dict): 66*f6aab3d8Srobert debugger.HandleCommand( 67*f6aab3d8Srobert "command script add -o -f stacks.stack_frames stack_frames") 68061da546Spatrick print("A new command called 'stack_frames' was added, type 'stack_frames --help' for more information.") 69