[Lldb-commits] [lldb] r318424 - Fixed up to use a class for the commands, renamed the commands and added a way to just dump the compile unit full paths and optionally their support files with the new "dump-files"command.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 16 09:14:48 PST 2017


Author: gclayton
Date: Thu Nov 16 09:14:48 2017
New Revision: 318424

URL: http://llvm.org/viewvc/llvm-project?rev=318424&view=rev
Log:
Fixed up to use a class for the commands, renamed the commands and added a way to just dump the compile unit full paths and optionally their support files with the new "dump-files"command.


Modified:
    lldb/trunk/examples/python/lldb_module_utils.py

Modified: lldb/trunk/examples/python/lldb_module_utils.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/lldb_module_utils.py?rev=318424&r1=318423&r2=318424&view=diff
==============================================================================
--- lldb/trunk/examples/python/lldb_module_utils.py (original)
+++ lldb/trunk/examples/python/lldb_module_utils.py Thu Nov 16 09:14:48 2017
@@ -7,72 +7,185 @@ import string
 import sys
 
 
-def create_dump_module_line_tables_options():
-    usage = "usage: dump_module_line_tables [options] MODULE1 [MODULE2 ...]"
-    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.'''
-    parser = optparse.OptionParser(
-        description=description,
-        prog='start_gdb_log',
-        usage=usage)
-    parser.add_option(
-        '-v',
-        '--verbose',
-        action='store_true',
-        dest='verbose',
-        help='Display verbose output.',
-        default=False)
-    return parser
-
-
-def dump_module_line_tables(debugger, command, result, dict):
-    '''Dumps all line tables from all compile units for any modules specified as arguments.'''
-    command_args = shlex.split(command)
-
-    parser = create_dump_module_line_tables_options()
-    try:
-        (options, args) = parser.parse_args(command_args)
-    except:
-        return
-    if command_args:
-        target = debugger.GetSelectedTarget()
-        lldb.target = target
-        for module_name in command_args:
-            result.PutCString('Searching for module "%s"' % (module_name,))
-            module_fspec = lldb.SBFileSpec(module_name, False)
-            module = target.FindModule(module_fspec)
-            if module:
-                for cu_idx in range(module.GetNumCompileUnits()):
-                    cu = module.GetCompileUnitAtIndex(cu_idx)
-                    result.PutCString("\n%s:" % (cu.file))
-                    for line_idx in range(cu.GetNumLineEntries()):
-                        line_entry = cu.GetLineEntryAtIndex(line_idx)
-                        start_file_addr = line_entry.addr.file_addr
-                        end_file_addr = line_entry.end_addr.file_addr
-                        # If the two addresses are equal, this line table entry
-                        # is a termination entry
-                        if options.verbose:
-                            if start_file_addr != end_file_addr:
-                                result.PutCString(
-                                    '[%#x - %#x): %s' %
-                                    (start_file_addr, end_file_addr, line_entry))
-                        else:
-                            if start_file_addr == end_file_addr:
-                                result.PutCString('%#x: END' %
-                                                  (start_file_addr))
-                            else:
-                                result.PutCString(
-                                    '%#x: %s' %
-                                    (start_file_addr, line_entry))
+class DumpLineTables:
+    command_name = "dump-line-tables"
+    short_decription = "Dumps full paths to compile unit files and optionally all line table files."
+    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.'
+    usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
+    def create_options(self):
+        self.parser = optparse.OptionParser(
+            description=self.description,
+            prog=self.command_name,
+            usage=self.usage)
+
+        self.parser.add_option(
+            '-v',
+            '--verbose',
+            action='store_true',
+            dest='verbose',
+            help='Display verbose output.',
+            default=False)
+
+    def get_short_help(self):
+        return self.short_decription
+
+    def get_long_help(self):
+        return self.help_string
+
+    def __init__(self, debugger, unused):
+        self.create_options()
+        self.help_string = self.parser.format_help()
+
+    def __call__(self, debugger, command, exe_ctx, result):
+        # Use the Shell Lexer to properly parse up command options just like a
+        # shell would
+        command_args = shlex.split(command)
+
+        try:
+            (options, args) = self.parser.parse_args(command_args)
+        except:
+            # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
+            # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
+            result.SetError("option parsing failed")
+            return
+
+        # Always get program state from the SBExecutionContext passed in as exe_ctx
+        target = exe_ctx.GetTarget()
+        if not target.IsValid():
+            result.SetError("invalid target")
+            return
+
+        for module_path in args:
+            module = target.module[module_path]
+            if not module:
+                result.SetError('no module found that matches "%s".' % (module_path))
+                return
+            num_cus = module.GetNumCompileUnits()
+            print >>result, 'Module: "%s"' % (module.file.fullpath),
+            if num_cus == 0:
+                print >>result, 'no debug info.'
+                continue
+            print >>result, 'has %u compile units:' % (num_cus)
+            for cu_idx in range(num_cus):
+                cu = module.GetCompileUnitAtIndex(cu_idx)
+                print >>result, '  Compile Unit: %s' % (cu.file.fullpath)
+                for line_idx in range(cu.GetNumLineEntries()):
+                    line_entry = cu.GetLineEntryAtIndex(line_idx)
+                    start_file_addr = line_entry.addr.file_addr
+                    end_file_addr = line_entry.end_addr.file_addr
+                    # If the two addresses are equal, this line table entry
+                    # is a termination entry
+                    if options.verbose:
+                        if start_file_addr != end_file_addr:
+                            result.PutCString(
+                                '    [%#x - %#x): %s' %
+                                (start_file_addr, end_file_addr, line_entry))
+                    else:
                         if start_file_addr == end_file_addr:
-                            result.Printf("\n")
-            else:
-                result.PutCString("no module for '%s'" % module)
-    else:
-        result.PutCString("error: invalid target")
-
-parser = create_dump_module_line_tables_options()
-dump_module_line_tables.__doc__ = parser.format_help()
-lldb.debugger.HandleCommand(
-    'command script add -f %s.dump_module_line_tables dump_module_line_tables' %
-    __name__)
-print 'Installed "dump_module_line_tables" command'
+                            result.PutCString('    %#x: END' %
+                                              (start_file_addr))
+                        else:
+                            result.PutCString(
+                                '    %#x: %s' %
+                                (start_file_addr, line_entry))
+                    if start_file_addr == end_file_addr:
+                        result.PutCString("\n")
+
+
+class DumpFiles:
+    command_name = "dump-files"
+    short_description = "Dumps full paths to compile unit files and optionally all line table files."
+    usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
+    description = '''This class adds a dump-files command to the LLDB interpreter.
+
+This command will dump all compile unit file paths found for each source file
+for the binaries specified as arguments in the current target. Specify the
+--support-files or -s option to see all file paths that a compile unit uses in
+its lines tables. This is handy for troubleshooting why breakpoints aren't
+working in IDEs that specify full paths to source files when setting file and
+line breakpoints. Sometimes symlinks cause the debug info to contain the symlink
+path and an IDE will resolve the path to the actual file and use the resolved
+path when setting breakpoints.
+'''
+    def create_options(self):
+        # Pass add_help_option = False, since this keeps the command in line with lldb commands,
+        # and we wire up "help command" to work by providing the long & short help methods below.
+        self.parser = optparse.OptionParser(
+            description = self.description,
+            prog = self.command_name,
+            usage = self.usage,
+            add_help_option = False)
+
+        self.parser.add_option(
+            '-s',
+            '--support-files',
+            action = 'store_true',
+            dest = 'support_files',
+            help = 'Dumps full paths to all files used in a compile unit.',
+            default = False)
+
+    def get_short_help(self):
+        return self.short_description
+
+    def get_long_help(self):
+        return self.help_string
+
+    def __init__(self, debugger, unused):
+        self.create_options()
+        self.help_string = self.parser.format_help()
+
+    def __call__(self, debugger, command, exe_ctx, result):
+        # Use the Shell Lexer to properly parse up command options just like a
+        # shell would
+        command_args = shlex.split(command)
+
+        try:
+            (options, args) = self.parser.parse_args(command_args)
+        except:
+            # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
+            # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
+            result.SetError("option parsing failed")
+            return
+
+        # Always get program state from the SBExecutionContext passed in as exe_ctx
+        target = exe_ctx.GetTarget()
+        if not target.IsValid():
+            result.SetError("invalid target")
+            return
+
+        if len(args) == 0:
+            result.SetError("one or more executable paths must be specified")
+            return
+
+        for module_path in args:
+            module = target.module[module_path]
+            if not module:
+                result.SetError('no module found that matches "%s".' % (module_path))
+                return
+            num_cus = module.GetNumCompileUnits()
+            print >>result, 'Module: "%s"' % (module.file.fullpath),
+            if num_cus == 0:
+                print >>result, 'no debug info.'
+                continue
+            print >>result, 'has %u compile units:' % (num_cus)
+            for i in range(num_cus):
+                cu = module.GetCompileUnitAtIndex(i)
+                print >>result, '  Compile Unit: %s' % (cu.file.fullpath)
+                if options.support_files:
+                    num_support_files = cu.GetNumSupportFiles()
+                    for j in range(num_support_files):
+                        path = cu.GetSupportFileAtIndex(j).fullpath
+                        print >>result, '    file[%u]: %s' % (j, path)
+
+
+def __lldb_init_module(debugger, dict):
+    # This initializer is being run from LLDB in the embedded command interpreter
+
+    # Add any commands contained in this module to LLDB
+    debugger.HandleCommand(
+        'command script add -c %s.DumpLineTables %s' % (__name__,
+                                                        DumpLineTables.command_name))
+    debugger.HandleCommand(
+        'command script add -c %s.DumpFiles %s' % (__name__, DumpFiles.command_name))
+    print 'The "%s" and "%s" commands have been installed.' % (DumpLineTables.command_name,
+                                                               DumpFiles.command_name)




More information about the lldb-commits mailing list