annotate lldb/examples/python/cmdtemplate.py @ 227:21e6aa2e49ef

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