Revert "[clang-repl] Implement partial translation units and error recovery."
[llvm-project.git] / lldb / examples / python / lldb_module_utils.py
blobc0ac5751ce285c5e4199f9c1a2a54af442dd63b3
1 #!/usr/bin/env python
2 from __future__ import print_function
4 import lldb
5 import optparse
6 import shlex
7 import string
8 import sys
11 class DumpLineTables:
12 command_name = "dump-line-tables"
13 short_decription = "Dumps full paths to compile unit files and optionally all line table files."
14 description = 'Dumps all line tables from all compile units for any modules specified as arguments. Specifying the --verbose flag will output address ranges for each line entry.'
15 usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
16 def create_options(self):
17 self.parser = optparse.OptionParser(
18 description=self.description,
19 prog=self.command_name,
20 usage=self.usage)
22 self.parser.add_option(
23 '-v',
24 '--verbose',
25 action='store_true',
26 dest='verbose',
27 help='Display verbose output.',
28 default=False)
30 def get_short_help(self):
31 return self.short_decription
33 def get_long_help(self):
34 return self.help_string
36 def __init__(self, debugger, unused):
37 self.create_options()
38 self.help_string = self.parser.format_help()
40 def __call__(self, debugger, command, exe_ctx, result):
41 # Use the Shell Lexer to properly parse up command options just like a
42 # shell would
43 command_args = shlex.split(command)
45 try:
46 (options, args) = self.parser.parse_args(command_args)
47 except:
48 # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
49 # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
50 result.SetError("option parsing failed")
51 return
53 # Always get program state from the SBExecutionContext passed in as exe_ctx
54 target = exe_ctx.GetTarget()
55 if not target.IsValid():
56 result.SetError("invalid target")
57 return
59 for module_path in args:
60 module = target.module[module_path]
61 if not module:
62 result.SetError('no module found that matches "%s".' % (module_path))
63 return
64 num_cus = module.GetNumCompileUnits()
65 print('Module: "%s"' % (module.file.fullpath), end=' ', file=result)
66 if num_cus == 0:
67 print('no debug info.', file=result)
68 continue
69 print('has %u compile units:' % (num_cus), file=result)
70 for cu_idx in range(num_cus):
71 cu = module.GetCompileUnitAtIndex(cu_idx)
72 print(' Compile Unit: %s' % (cu.file.fullpath), file=result)
73 for line_idx in range(cu.GetNumLineEntries()):
74 line_entry = cu.GetLineEntryAtIndex(line_idx)
75 start_file_addr = line_entry.addr.file_addr
76 end_file_addr = line_entry.end_addr.file_addr
77 # If the two addresses are equal, this line table entry
78 # is a termination entry
79 if options.verbose:
80 if start_file_addr != end_file_addr:
81 result.PutCString(
82 ' [%#x - %#x): %s' %
83 (start_file_addr, end_file_addr, line_entry))
84 else:
85 if start_file_addr == end_file_addr:
86 result.PutCString(' %#x: END' %
87 (start_file_addr))
88 else:
89 result.PutCString(
90 ' %#x: %s' %
91 (start_file_addr, line_entry))
92 if start_file_addr == end_file_addr:
93 result.PutCString("\n")
96 class DumpFiles:
97 command_name = "dump-files"
98 short_description = "Dumps full paths to compile unit files and optionally all line table files."
99 usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
100 description = '''This class adds a dump-files command to the LLDB interpreter.
102 This command will dump all compile unit file paths found for each source file
103 for the binaries specified as arguments in the current target. Specify the
104 --support-files or -s option to see all file paths that a compile unit uses in
105 its lines tables. This is handy for troubleshooting why breakpoints aren't
106 working in IDEs that specify full paths to source files when setting file and
107 line breakpoints. Sometimes symlinks cause the debug info to contain the symlink
108 path and an IDE will resolve the path to the actual file and use the resolved
109 path when setting breakpoints.
111 def create_options(self):
112 # Pass add_help_option = False, since this keeps the command in line with lldb commands,
113 # and we wire up "help command" to work by providing the long & short help methods below.
114 self.parser = optparse.OptionParser(
115 description = self.description,
116 prog = self.command_name,
117 usage = self.usage,
118 add_help_option = False)
120 self.parser.add_option(
121 '-s',
122 '--support-files',
123 action = 'store_true',
124 dest = 'support_files',
125 help = 'Dumps full paths to all files used in a compile unit.',
126 default = False)
128 def get_short_help(self):
129 return self.short_description
131 def get_long_help(self):
132 return self.help_string
134 def __init__(self, debugger, unused):
135 self.create_options()
136 self.help_string = self.parser.format_help()
138 def __call__(self, debugger, command, exe_ctx, result):
139 # Use the Shell Lexer to properly parse up command options just like a
140 # shell would
141 command_args = shlex.split(command)
143 try:
144 (options, args) = self.parser.parse_args(command_args)
145 except:
146 # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
147 # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
148 result.SetError("option parsing failed")
149 return
151 # Always get program state from the SBExecutionContext passed in as exe_ctx
152 target = exe_ctx.GetTarget()
153 if not target.IsValid():
154 result.SetError("invalid target")
155 return
157 if len(args) == 0:
158 result.SetError("one or more executable paths must be specified")
159 return
161 for module_path in args:
162 module = target.module[module_path]
163 if not module:
164 result.SetError('no module found that matches "%s".' % (module_path))
165 return
166 num_cus = module.GetNumCompileUnits()
167 print('Module: "%s"' % (module.file.fullpath), end=' ', file=result)
168 if num_cus == 0:
169 print('no debug info.', file=result)
170 continue
171 print('has %u compile units:' % (num_cus), file=result)
172 for i in range(num_cus):
173 cu = module.GetCompileUnitAtIndex(i)
174 print(' Compile Unit: %s' % (cu.file.fullpath), file=result)
175 if options.support_files:
176 num_support_files = cu.GetNumSupportFiles()
177 for j in range(num_support_files):
178 path = cu.GetSupportFileAtIndex(j).fullpath
179 print(' file[%u]: %s' % (j, path), file=result)
182 def __lldb_init_module(debugger, dict):
183 # This initializer is being run from LLDB in the embedded command interpreter
185 # Add any commands contained in this module to LLDB
186 debugger.HandleCommand(
187 'command script add -c %s.DumpLineTables %s' % (__name__,
188 DumpLineTables.command_name))
189 debugger.HandleCommand(
190 'command script add -c %s.DumpFiles %s' % (__name__, DumpFiles.command_name))
191 print('The "%s" and "%s" commands have been installed.' % (DumpLineTables.command_name,
192 DumpFiles.command_name))