CVS Repository/ srcgnullvmlldbexamplespython/ cmdtemplate.py

Annotated Revision  1.1.1.1  Back
1.1
 (patrick  03-Aug-20) 
1
: #!/usr/bin/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
: from __future__ import print_function
1.1
 (patrick  03-Aug-20) 
13
: 
1.1
 (patrick  03-Aug-20) 
14
: import inspect
1.1
 (patrick  03-Aug-20) 
15
: import lldb
1.1
 (patrick  03-Aug-20) 
16
: import optparse
1.1
 (patrick  03-Aug-20) 
17
: import shlex
1.1
 (patrick  03-Aug-20) 
18
: import sys
1.1
 (patrick  03-Aug-20) 
19
: 
1.1
 (patrick  03-Aug-20) 
20
: 
1.1
 (patrick  03-Aug-20) 
21
: class FrameStatCommand:
1.1
 (patrick  03-Aug-20) 
22
:     program = 'framestats'
1.1
 (patrick  03-Aug-20) 
23
: 
1.1
 (patrick  03-Aug-20) 
24
:     @classmethod
1.1
 (patrick  03-Aug-20) 
25
:     def register_lldb_command(cls, debugger, module_name):
1.1
 (patrick  03-Aug-20) 
26
:         parser = cls.create_options()
1.1
 (patrick  03-Aug-20) 
27
:         cls.__doc__ = parser.format_help()
1.1
 (patrick  03-Aug-20) 
28
:         # Add any commands contained in this module to LLDB
1.1
 (patrick  03-Aug-20) 
29
:         command = 'command script add -c %s.%s %s' % (module_name,
1.1
 (patrick  03-Aug-20) 
30
:                                                       cls.__name__,
1.1
 (patrick  03-Aug-20) 
31
:                                                       cls.program)
1.1
 (patrick  03-Aug-20) 
32
:         debugger.HandleCommand(command)
1.1
 (patrick  03-Aug-20) 
33
:         print('The "{0}" command has been installed, type "help {0}" or "{0} '
1.1
 (patrick  03-Aug-20) 
34
:               '--help" for detailed help.'.format(cls.program))
1.1
 (patrick  03-Aug-20) 
35
: 
1.1
 (patrick  03-Aug-20) 
36
:     @classmethod
1.1
 (patrick  03-Aug-20) 
37
:     def create_options(cls):
1.1
 (patrick  03-Aug-20) 
38
: 
1.1
 (patrick  03-Aug-20) 
39
:         usage = "usage: %prog [options]"
1.1
 (patrick  03-Aug-20) 
40
:         description = ('This command is meant to be an example of how to make '
1.1
 (patrick  03-Aug-20) 
41
:                        'an LLDB command that does something useful, follows '
1.1
 (patrick  03-Aug-20) 
42
:                        'best practices, and exploits the SB API. '
1.1
 (patrick  03-Aug-20) 
43
:                        'Specifically, this command computes the aggregate '
1.1
 (patrick  03-Aug-20) 
44
:                        'and average size of the variables in the current '
1.1
 (patrick  03-Aug-20) 
45
:                        'frame and allows you to tweak exactly which variables '
1.1
 (patrick  03-Aug-20) 
46
:                        'are to be accounted in the computation.')
1.1
 (patrick  03-Aug-20) 
47
: 
1.1
 (patrick  03-Aug-20) 
48
:         # Pass add_help_option = False, since this keeps the command in line
1.1
 (patrick  03-Aug-20) 
49
:         #  with lldb commands, and we wire up "help command" to work by
1.1
 (patrick  03-Aug-20) 
50
:         # providing the long & short help methods below.
1.1
 (patrick  03-Aug-20) 
51
:         parser = optparse.OptionParser(
1.1
 (patrick  03-Aug-20) 
52
:             description=description,
1.1
 (patrick  03-Aug-20) 
53
:             prog=cls.program,
1.1
 (patrick  03-Aug-20) 
54
:             usage=usage,
1.1
 (patrick  03-Aug-20) 
55
:             add_help_option=False)
1.1
 (patrick  03-Aug-20) 
56
: 
1.1
 (patrick  03-Aug-20) 
57
:         parser.add_option(
1.1
 (patrick  03-Aug-20) 
58
:             '-i',
1.1
 (patrick  03-Aug-20) 
59
:             '--in-scope',
1.1
 (patrick  03-Aug-20) 
60
:             action='store_true',
1.1
 (patrick  03-Aug-20) 
61
:             dest='inscope',
1.1
 (patrick  03-Aug-20) 
62
:             help='in_scope_only = True',
1.1
 (patrick  03-Aug-20) 
63
:             default=True)
1.1
 (patrick  03-Aug-20) 
64
: 
1.1
 (patrick  03-Aug-20) 
65
:         parser.add_option(
1.1
 (patrick  03-Aug-20) 
66
:             '-a',
1.1
 (patrick  03-Aug-20) 
67
:             '--arguments',
1.1
 (patrick  03-Aug-20) 
68
:             action='store_true',
1.1
 (patrick  03-Aug-20) 
69
:             dest='arguments',
1.1
 (patrick  03-Aug-20) 
70
:             help='arguments = True',
1.1
 (patrick  03-Aug-20) 
71
:             default=True)
1.1
 (patrick  03-Aug-20) 
72
: 
1.1
 (patrick  03-Aug-20) 
73
:         parser.add_option(
1.1
 (patrick  03-Aug-20) 
74
:             '-l',
1.1
 (patrick  03-Aug-20) 
75
:             '--locals',
1.1
 (patrick  03-Aug-20) 
76
:             action='store_true',
1.1
 (patrick  03-Aug-20) 
77
:             dest='locals',
1.1
 (patrick  03-Aug-20) 
78
:             help='locals = True',
1.1
 (patrick  03-Aug-20) 
79
:             default=True)
1.1
 (patrick  03-Aug-20) 
80
: 
1.1
 (patrick  03-Aug-20) 
81
:         parser.add_option(
1.1
 (patrick  03-Aug-20) 
82
:             '-s',
1.1
 (patrick  03-Aug-20) 
83
:             '--statics',
1.1
 (patrick  03-Aug-20) 
84
:             action='store_true',
1.1
 (patrick  03-Aug-20) 
85
:             dest='statics',
1.1
 (patrick  03-Aug-20) 
86
:             help='statics = True',
1.1
 (patrick  03-Aug-20) 
87
:             default=True)
1.1
 (patrick  03-Aug-20) 
88
: 
1.1
 (patrick  03-Aug-20) 
89
:         return parser
1.1
 (patrick  03-Aug-20) 
90
: 
1.1
 (patrick  03-Aug-20) 
91
:     def get_short_help(self):
1.1
 (patrick  03-Aug-20) 
92
:         return "Example command for use in debugging"
1.1
 (patrick  03-Aug-20) 
93
: 
1.1
 (patrick  03-Aug-20) 
94
:     def get_long_help(self):
1.1
 (patrick  03-Aug-20) 
95
:         return self.help_string
1.1
 (patrick  03-Aug-20) 
96
: 
1.1
 (patrick  03-Aug-20) 
97
:     def __init__(self, debugger, unused):
1.1
 (patrick  03-Aug-20) 
98
:         self.parser = self.create_options()
1.1
 (patrick  03-Aug-20) 
99
:         self.help_string = self.parser.format_help()
1.1
 (patrick  03-Aug-20) 
100
: 
1.1
 (patrick  03-Aug-20) 
101
:     def __call__(self, debugger, command, exe_ctx, result):
1.1
 (patrick  03-Aug-20) 
102
:         # Use the Shell Lexer to properly parse up command options just like a
1.1
 (patrick  03-Aug-20) 
103
:         # shell would
1.1
 (patrick  03-Aug-20) 
104
:         command_args = shlex.split(command)
1.1
 (patrick  03-Aug-20) 
105
: 
1.1
 (patrick  03-Aug-20) 
106
:         try:
1.1
 (patrick  03-Aug-20) 
107
:             (options, args) = self.parser.parse_args(command_args)
1.1
 (patrick  03-Aug-20) 
108
:         except:
1.1
 (patrick  03-Aug-20) 
109
:             # if you don't handle exceptions, passing an incorrect argument to
1.1
 (patrick  03-Aug-20) 
110
:             # the OptionParser will cause LLDB to exit (courtesy of OptParse
1.1
 (patrick  03-Aug-20) 
111
:             # dealing with argument errors by throwing SystemExit)
1.1
 (patrick  03-Aug-20) 
112
:             result.SetError("option parsing failed")
1.1
 (patrick  03-Aug-20) 
113
:             return
1.1
 (patrick  03-Aug-20) 
114
: 
1.1
 (patrick  03-Aug-20) 
115
:         # Always get program state from the lldb.SBExecutionContext passed
1.1
 (patrick  03-Aug-20) 
116
:         # in as exe_ctx
1.1
 (patrick  03-Aug-20) 
117
:         frame = exe_ctx.GetFrame()
1.1
 (patrick  03-Aug-20) 
118
:         if not frame.IsValid():
1.1
 (patrick  03-Aug-20) 
119
:             result.SetError("invalid frame")
1.1
 (patrick  03-Aug-20) 
120
:             return
1.1
 (patrick  03-Aug-20) 
121
: 
1.1
 (patrick  03-Aug-20) 
122
:         variables_list = frame.GetVariables(
1.1
 (patrick  03-Aug-20) 
123
:             options.arguments,
1.1
 (patrick  03-Aug-20) 
124
:             options.locals,
1.1
 (patrick  03-Aug-20) 
125
:             options.statics,
1.1
 (patrick  03-Aug-20) 
126
:             options.inscope)
1.1
 (patrick  03-Aug-20) 
127
:         variables_count = variables_list.GetSize()
1.1
 (patrick  03-Aug-20) 
128
:         if variables_count == 0:
1.1
 (patrick  03-Aug-20) 
129
:             print("no variables here", file=result)
1.1
 (patrick  03-Aug-20) 
130
:             return
1.1
 (patrick  03-Aug-20) 
131
:         total_size = 0
1.1
 (patrick  03-Aug-20) 
132
:         for i in range(0, variables_count):
1.1
 (patrick  03-Aug-20) 
133
:             variable = variables_list.GetValueAtIndex(i)
1.1
 (patrick  03-Aug-20) 
134
:             variable_type = variable.GetType()
1.1
 (patrick  03-Aug-20) 
135
:             total_size = total_size + variable_type.GetByteSize()
1.1
 (patrick  03-Aug-20) 
136
:             average_size = float(total_size) / variables_count
1.1
 (patrick  03-Aug-20) 
137
:             print("Your frame has %d variables. Their total size "
1.1
 (patrick  03-Aug-20) 
138
:                              "is %d bytes. The average size is %f bytes" % (
1.1
 (patrick  03-Aug-20) 
139
:                                     variables_count, total_size, average_size), file=result)
1.1
 (patrick  03-Aug-20) 
140
:         # not returning anything is akin to returning success
1.1
 (patrick  03-Aug-20) 
141
: 
1.1
 (patrick  03-Aug-20) 
142
: 
1.1
 (patrick  03-Aug-20) 
143
: def __lldb_init_module(debugger, dict):
1.1
 (patrick  03-Aug-20) 
144
:     # Register all classes that have a register_lldb_command method
1.1
 (patrick  03-Aug-20) 
145
:     for _name, cls in inspect.getmembers(sys.modules[__name__]):
1.1
 (patrick  03-Aug-20) 
146
:         if inspect.isclass(cls) and callable(getattr(cls,
1.1
 (patrick  03-Aug-20) 
147
:                                                      "register_lldb_command",
1.1
 (patrick  03-Aug-20) 
148
:                                                      None)):
1.1
 (patrick  03-Aug-20) 
149
:             cls.register_lldb_command(debugger, __name__)