xref: /openbsd-src/gnu/llvm/lldb/examples/python/stacks.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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