1.1.1.2
|
(patrick 17-Dec-21)
| 1
|
: #!/usr/bin/env python
|
1.1
|
(patrick 03-Aug-20)
| 2
|
:
|
1.1
|
(patrick 03-Aug-20)
| 3
|
: # ---------------------------------------------------------------------
|
1.1
|
(patrick 03-Aug-20)
| 4
|
: # Be sure to add the python path that points to the LLDB shared library.
|
1.1
|
(patrick 03-Aug-20)
| 5
|
: #
|
1.1
|
(patrick 03-Aug-20)
| 6
|
: # # To use this in the embedded python interpreter using "lldb" just
|
1.1
|
(patrick 03-Aug-20)
| 7
|
: # import it with the full path using the "command script import"
|
1.1
|
(patrick 03-Aug-20)
| 8
|
: # command
|
1.1
|
(patrick 03-Aug-20)
| 9
|
: # (lldb) command script import /path/to/cmdtemplate.py
|
1.1
|
(patrick 03-Aug-20)
| 10
|
: # ---------------------------------------------------------------------
|
1.1
|
(patrick 03-Aug-20)
| 11
|
:
|
1.1
|
(patrick 03-Aug-20)
| 12
|
: import inspect
|
1.1
|
(patrick 03-Aug-20)
| 13
|
: import lldb
|
1.1
|
(patrick 03-Aug-20)
| 14
|
: import sys
|
1.1.1.4
|
(robert 11-Jun-25)
| 15
|
: from lldb.plugins.parsed_cmd import ParsedCommand
|
1.1
|
(patrick 03-Aug-20)
| 16
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 17
|
: class FrameStatCommand(ParsedCommand):
|
1.1.1.4
|
(robert 11-Jun-25)
| 18
|
: program = "framestats"
|
1.1
|
(patrick 03-Aug-20)
| 19
|
:
|
1.1
|
(patrick 03-Aug-20)
| 20
|
: @classmethod
|
1.1
|
(patrick 03-Aug-20)
| 21
|
: def register_lldb_command(cls, debugger, module_name):
|
1.1.1.4
|
(robert 11-Jun-25)
| 22
|
: ParsedCommand.do_register_cmd(cls, debugger, module_name)
|
1.1.1.4
|
(robert 11-Jun-25)
| 23
|
: print(
|
1.1.1.4
|
(robert 11-Jun-25)
| 24
|
: 'The "{0}" command has been installed, type "help {0}" or "{0} '
|
1.1.1.4
|
(robert 11-Jun-25)
| 25
|
: '--help" for detailed help.'.format(cls.program)
|
1.1.1.4
|
(robert 11-Jun-25)
| 26
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 27
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 28
|
: def setup_command_definition(self):
|
1.1.1.4
|
(robert 11-Jun-25)
| 29
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 30
|
: self.ov_parser.add_option(
|
1.1.1.4
|
(robert 11-Jun-25)
| 31
|
: "i",
|
1.1.1.4
|
(robert 11-Jun-25)
| 32
|
: "in-scope",
|
1.1.1.4
|
(robert 11-Jun-25)
| 33
|
: help = "in_scope_only = True",
|
1.1.1.4
|
(robert 11-Jun-25)
| 34
|
: value_type = lldb.eArgTypeBoolean,
|
1.1.1.4
|
(robert 11-Jun-25)
| 35
|
: dest = "bool_arg",
|
1.1.1.4
|
(robert 11-Jun-25)
| 36
|
: default = True,
|
1.1.1.4
|
(robert 11-Jun-25)
| 37
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 38
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 39
|
: self.ov_parser.add_option(
|
1.1.1.4
|
(robert 11-Jun-25)
| 40
|
: "i",
|
1.1.1.4
|
(robert 11-Jun-25)
| 41
|
: "in-scope",
|
1.1.1.4
|
(robert 11-Jun-25)
| 42
|
: help = "in_scope_only = True",
|
1.1.1.4
|
(robert 11-Jun-25)
| 43
|
: value_type = lldb.eArgTypeBoolean,
|
1.1.1.4
|
(robert 11-Jun-25)
| 44
|
: dest = "inscope",
|
1.1.1.4
|
(robert 11-Jun-25)
| 45
|
: default=True,
|
1.1.1.4
|
(robert 11-Jun-25)
| 46
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 47
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 48
|
: self.ov_parser.add_option(
|
1.1.1.4
|
(robert 11-Jun-25)
| 49
|
: "a",
|
1.1.1.4
|
(robert 11-Jun-25)
| 50
|
: "arguments",
|
1.1.1.4
|
(robert 11-Jun-25)
| 51
|
: help = "arguments = True",
|
1.1.1.4
|
(robert 11-Jun-25)
| 52
|
: value_type = lldb.eArgTypeBoolean,
|
1.1.1.4
|
(robert 11-Jun-25)
| 53
|
: dest = "arguments",
|
1.1.1.4
|
(robert 11-Jun-25)
| 54
|
: default = True,
|
1.1.1.4
|
(robert 11-Jun-25)
| 55
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 56
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 57
|
: self.ov_parser.add_option(
|
1.1.1.4
|
(robert 11-Jun-25)
| 58
|
: "l",
|
1.1.1.4
|
(robert 11-Jun-25)
| 59
|
: "locals",
|
1.1.1.4
|
(robert 11-Jun-25)
| 60
|
: help = "locals = True",
|
1.1.1.4
|
(robert 11-Jun-25)
| 61
|
: value_type = lldb.eArgTypeBoolean,
|
1.1.1.4
|
(robert 11-Jun-25)
| 62
|
: dest = "locals",
|
1.1.1.4
|
(robert 11-Jun-25)
| 63
|
: default = True,
|
1.1.1.4
|
(robert 11-Jun-25)
| 64
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 65
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 66
|
: self.ov_parser.add_option(
|
1.1.1.4
|
(robert 11-Jun-25)
| 67
|
: "s",
|
1.1.1.4
|
(robert 11-Jun-25)
| 68
|
: "statics",
|
1.1.1.4
|
(robert 11-Jun-25)
| 69
|
: help = "statics = True",
|
1.1.1.4
|
(robert 11-Jun-25)
| 70
|
: value_type = lldb.eArgTypeBoolean,
|
1.1.1.4
|
(robert 11-Jun-25)
| 71
|
: dest = "statics",
|
1.1.1.4
|
(robert 11-Jun-25)
| 72
|
: default = True,
|
1.1.1.4
|
(robert 11-Jun-25)
| 73
|
: )
|
1.1.1.4
|
(robert 11-Jun-25)
| 74
|
:
|
1.1.1.4
|
(robert 11-Jun-25)
| 75
|
: def get_repeat_command(self, args):
|
1.1.1.4
|
(robert 11-Jun-25)
| 76
|
: """As an example, make the command not auto-repeat:"""
|
1.1.1.4
|
(robert 11-Jun-25)
| 77
|
: return ""
|
1.1
|
(patrick 03-Aug-20)
| 78
|
:
|
1.1
|
(patrick 03-Aug-20)
| 79
|
: def get_short_help(self):
|
1.1
|
(patrick 03-Aug-20)
| 80
|
: return "Example command for use in debugging"
|
1.1
|
(patrick 03-Aug-20)
| 81
|
:
|
1.1
|
(patrick 03-Aug-20)
| 82
|
: def get_long_help(self):
|
1.1.1.4
|
(robert 11-Jun-25)
| 83
|
: return ("This command is meant to be an example of how to make "
|
1.1.1.4
|
(robert 11-Jun-25)
| 84
|
: "an LLDB command that does something useful, follows "
|
1.1.1.4
|
(robert 11-Jun-25)
| 85
|
: "best practices, and exploits the SB API. "
|
1.1.1.4
|
(robert 11-Jun-25)
| 86
|
: "Specifically, this command computes the aggregate "
|
1.1.1.4
|
(robert 11-Jun-25)
| 87
|
: "and average size of the variables in the current "
|
1.1.1.4
|
(robert 11-Jun-25)
| 88
|
: "frame and allows you to tweak exactly which variables "
|
1.1.1.4
|
(robert 11-Jun-25)
| 89
|
: "are to be accounted in the computation.")
|
1.1.1.4
|
(robert 11-Jun-25)
| 90
|
:
|
1.1
|
(patrick 03-Aug-20)
| 91
|
:
|
1.1
|
(patrick 03-Aug-20)
| 92
|
: def __init__(self, debugger, unused):
|
1.1.1.4
|
(robert 11-Jun-25)
| 93
|
: super().__init__(debugger, unused)
|
1.1
|
(patrick 03-Aug-20)
| 94
|
:
|
1.1
|
(patrick 03-Aug-20)
| 95
|
: def __call__(self, debugger, command, exe_ctx, result):
|
1.1
|
(patrick 03-Aug-20)
| 96
|
: # Always get program state from the lldb.SBExecutionContext passed
|
1.1
|
(patrick 03-Aug-20)
| 97
|
: # in as exe_ctx
|
1.1
|
(patrick 03-Aug-20)
| 98
|
: frame = exe_ctx.GetFrame()
|
1.1
|
(patrick 03-Aug-20)
| 99
|
: if not frame.IsValid():
|
1.1
|
(patrick 03-Aug-20)
| 100
|
: result.SetError("invalid frame")
|
1.1
|
(patrick 03-Aug-20)
| 101
|
: return
|
1.1
|
(patrick 03-Aug-20)
| 102
|
:
|
1.1
|
(patrick 03-Aug-20)
| 103
|
: variables_list = frame.GetVariables(
|
1.1.1.4
|
(robert 11-Jun-25)
| 104
|
: self.ov_parser.arguments, self.ov_parser.locals, self.ov_parser.statics, self.ov_parser.inscope
|
1.1.1.4
|
(robert 11-Jun-25)
| 105
|
: )
|
1.1
|
(patrick 03-Aug-20)
| 106
|
: variables_count = variables_list.GetSize()
|
1.1
|
(patrick 03-Aug-20)
| 107
|
: if variables_count == 0:
|
1.1
|
(patrick 03-Aug-20)
| 108
|
: print("no variables here", file=result)
|
1.1
|
(patrick 03-Aug-20)
| 109
|
: return
|
1.1
|
(patrick 03-Aug-20)
| 110
|
: total_size = 0
|
1.1
|
(patrick 03-Aug-20)
| 111
|
: for i in range(0, variables_count):
|
1.1
|
(patrick 03-Aug-20)
| 112
|
: variable = variables_list.GetValueAtIndex(i)
|
1.1
|
(patrick 03-Aug-20)
| 113
|
: variable_type = variable.GetType()
|
1.1
|
(patrick 03-Aug-20)
| 114
|
: total_size = total_size + variable_type.GetByteSize()
|
1.1
|
(patrick 03-Aug-20)
| 115
|
: average_size = float(total_size) / variables_count
|
1.1.1.4
|
(robert 11-Jun-25)
| 116
|
: print(
|
1.1.1.4
|
(robert 11-Jun-25)
| 117
|
: "Your frame has %d variables. Their total size "
|
1.1.1.4
|
(robert 11-Jun-25)
| 118
|
: "is %d bytes. The average size is %f bytes"
|
1.1.1.4
|
(robert 11-Jun-25)
| 119
|
: % (variables_count, total_size, average_size),
|
1.1.1.4
|
(robert 11-Jun-25)
| 120
|
: file=result,
|
1.1.1.4
|
(robert 11-Jun-25)
| 121
|
: )
|
1.1
|
(patrick 03-Aug-20)
| 122
|
: # not returning anything is akin to returning success
|
1.1
|
(patrick 03-Aug-20)
| 123
|
:
|
1.1
|
(patrick 03-Aug-20)
| 124
|
:
|
1.1
|
(patrick 03-Aug-20)
| 125
|
: def __lldb_init_module(debugger, dict):
|
1.1
|
(patrick 03-Aug-20)
| 126
|
: # Register all classes that have a register_lldb_command method
|
1.1
|
(patrick 03-Aug-20)
| 127
|
: for _name, cls in inspect.getmembers(sys.modules[__name__]):
|
1.1.1.4
|
(robert 11-Jun-25)
| 128
|
: if inspect.isclass(cls) and callable(
|
1.1.1.4
|
(robert 11-Jun-25)
| 129
|
: getattr(cls, "register_lldb_command", None)
|
1.1.1.4
|
(robert 11-Jun-25)
| 130
|
: ):
|
1.1
|
(patrick 03-Aug-20)
| 131
|
: cls.register_lldb_command(debugger, __name__)
|