1515bc8c1Sserge-sans-paille#!/usr/bin/env python 2525cd59fSSerge Gueltonfrom __future__ import print_function 36b152ff5SGreg Claytonimport lldb 46b152ff5SGreg Claytonimport optparse 56b152ff5SGreg Claytonimport shlex 66b152ff5SGreg Clayton 7b9c1b51eSKate Stone 86b152ff5SGreg Claytondef stack_frames(debugger, command, result, dict): 96b152ff5SGreg Clayton command_args = shlex.split(command) 106b152ff5SGreg Clayton usage = "usage: %prog [options] <PATH> [PATH ...]" 116b152ff5SGreg Clayton 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.''' 12b9c1b51eSKate Stone parser = optparse.OptionParser( 13b9c1b51eSKate Stone description=description, prog='ls', usage=usage) 14b9c1b51eSKate Stone parser.add_option( 15b9c1b51eSKate Stone '-v', 16b9c1b51eSKate Stone '--verbose', 17b9c1b51eSKate Stone action='store_true', 18b9c1b51eSKate Stone dest='verbose', 19b9c1b51eSKate Stone help='display verbose debug info', 20b9c1b51eSKate Stone default=False) 216b152ff5SGreg Clayton try: 226b152ff5SGreg Clayton (options, args) = parser.parse_args(command_args) 236b152ff5SGreg Clayton except: 246b152ff5SGreg Clayton return 256b152ff5SGreg Clayton 26bca7db71SGreg Clayton target = debugger.GetSelectedTarget() 27bca7db71SGreg Clayton process = target.GetProcess() 28bca7db71SGreg Clayton 296b152ff5SGreg Clayton frame_info = {} 30bca7db71SGreg Clayton for thread in process: 316b152ff5SGreg Clayton last_frame = None 32525cd59fSSerge Guelton print("thread %u" % (thread.id)) 336b152ff5SGreg Clayton for frame in thread.frames: 346b152ff5SGreg Clayton if last_frame: 356b152ff5SGreg Clayton frame_size = 0 366b152ff5SGreg Clayton if frame.idx == 1: 376b152ff5SGreg Clayton if frame.fp == last_frame.fp: 38b9c1b51eSKate Stone # No frame one the first frame (might be right at the 39b9c1b51eSKate Stone # entry point) 406b152ff5SGreg Clayton first_frame_size = 0 416b152ff5SGreg Clayton frame_size = frame.fp - frame.sp 426b152ff5SGreg Clayton else: 436b152ff5SGreg Clayton # First frame that has a valid size 446b152ff5SGreg Clayton first_frame_size = last_frame.fp - last_frame.sp 45525cd59fSSerge Guelton print("<%#7x> %s" % (first_frame_size, last_frame)) 466b152ff5SGreg Clayton if first_frame_size: 476b152ff5SGreg Clayton name = last_frame.name 486b152ff5SGreg Clayton if name not in frame_info: 496b152ff5SGreg Clayton frame_info[name] = first_frame_size 506b152ff5SGreg Clayton else: 516b152ff5SGreg Clayton frame_info[name] += first_frame_size 526b152ff5SGreg Clayton else: 536b152ff5SGreg Clayton # Second or higher frame 546b152ff5SGreg Clayton frame_size = frame.fp - last_frame.fp 55525cd59fSSerge Guelton print("<%#7x> %s" % (frame_size, frame)) 566b152ff5SGreg Clayton if frame_size > 0: 576b152ff5SGreg Clayton name = frame.name 586b152ff5SGreg Clayton if name not in frame_info: 596b152ff5SGreg Clayton frame_info[name] = frame_size 606b152ff5SGreg Clayton else: 616b152ff5SGreg Clayton frame_info[name] += frame_size 626b152ff5SGreg Clayton last_frame = frame 63525cd59fSSerge Guelton print(frame_info) 646b152ff5SGreg Clayton 656b152ff5SGreg Clayton 66*1441ffe6SDave Leedef __lldb_init_module(debugger, internal_dict): 67*1441ffe6SDave Lee debugger.HandleCommand( 68b9c1b51eSKate Stone "command script add -f stacks.stack_frames stack_frames") 69525cd59fSSerge Guelton print("A new command called 'stack_frames' was added, type 'stack_frames --help' for more information.") 70