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