File indexing completed on 2024-04-21 05:41:53

0001 # Creates GDB autoloader scripts for the Qt5 pretty-printers
0002 #
0003 # Create a directory for autoload scripts, like
0004 # /home/myself/.gdb-autoload
0005 #
0006 # Add this directory to the GDB auto-load scripts-directory and
0007 # safe-path settings in your ~/.gdbinit
0008 #   set auto-load scripts-directory $debugdir:$datadir/auto-load:/home/myself/.gdb-autoload
0009 #   set auto-load safe-path $debugdir:$datadir/auto-load:/home/myself/.gdb-autoload
0010 #
0011 # Run this script as
0012 #   python create-qt5-autoloaders.py /home/myself/.gdb-autoload /usr/lib
0013 # where /usr/lib should be replaced with the directory containing the
0014 # Qt5 libraries (libQt5Core.so.5.*, etc)
0015 #
0016 # GDB will then auto-load the Qt5 pretty printers whenever the Qt5
0017 # libraries are loaded (and unload them again when they are unloaded).
0018 #
0019 
0020 
0021 # Copyright 2014 Alex Merry <alex.merry@kde.org>
0022 #
0023 # Permission to use, copy, modify, and distribute this software
0024 # and its documentation for any purpose and without fee is hereby
0025 # granted, provided that the above copyright notice appear in all
0026 # copies and that both that the copyright notice and this
0027 # permission notice and warranty disclaimer appear in supporting
0028 # documentation, and that the name of the author not be used in
0029 # advertising or publicity pertaining to distribution of the
0030 # software without specific, written prior permission.
0031 #
0032 # The author disclaims all warranties with regard to this
0033 # software, including all implied warranties of merchantability
0034 # and fitness.  In no event shall the author be liable for any
0035 # special, indirect or consequential damages or any damages
0036 # whatsoever resulting from loss of use, data or profits, whether
0037 # in an action of contract, negligence or other tortious action,
0038 # arising out of or in connection with the use or performance of
0039 # this software.
0040 
0041 
0042 import glob
0043 import os
0044 import os.path
0045 import re
0046 import sys
0047 
0048 if len(sys.argv) != 3:
0049     print ("Bad number of arguments to " + sys.argv[0])
0050     print ("See the comments at the top of the script for usage")
0051     sys.exit(1)
0052 
0053 autoloaddir = sys.argv[1]
0054 libdir = sys.argv[2]
0055 
0056 if not os.path.isdir(autoloaddir):
0057     print (autoloaddir + " is not a directory")
0058     print ("See the comments at the top of the script for usage")
0059     sys.exit(1)
0060 
0061 autoloaddir = os.path.abspath(autoloaddir)
0062 
0063 if not os.path.isdir(libdir):
0064     print (libdir + " is not a directory")
0065     print ("See the comments at the top of the script for usage")
0066     sys.exit(1)
0067 
0068 libdir = os.path.abspath(libdir)
0069 
0070 candidates = glob.iglob(libdir + "/*Qt5*")
0071 
0072 file_contents = """
0073 import gdb.printing
0074 
0075 moddir = "{0}"
0076 if not moddir in sys.path:
0077     sys.path.insert(0, moddir)
0078 
0079 import qt5printers.{{0}}
0080 gdb.printing.register_pretty_printer(gdb.current_objfile(), qt5printers.{{0}}.printer)
0081 """.format(os.path.abspath(os.path.dirname(__file__)))
0082 
0083 # NB: this works on Linux; the stuff for other platforms is my best
0084 #     guess for what those files look like
0085 mod_re = re.compile(r"(?:lib)?Qt5([^.]*)\.(?:so\.5\..*|dll|.*\.dylib)", re.I)
0086 
0087 # keep track of what files we have generated, as we may encounter some
0088 # that are symlinks to others (and we resolve all the symlinks)
0089 seen = set()
0090 
0091 for lib in candidates:
0092     lib = os.path.realpath(os.path.abspath(lib))
0093     if not lib in seen:
0094         target_filename = autoloaddir + lib + "-gdb.py"
0095         filename = os.path.basename(lib)
0096         match = mod_re.match(filename)
0097         if not match is None:
0098             seen.add(lib)
0099             module = match.group(1).lower()
0100             if os.path.exists('qt5printers/' + module + '.py') or os.path.exists('qt5printers/' + module + '/__init__.py'):
0101                 if not os.path.isdir(os.path.dirname(target_filename)):
0102                     os.makedirs(os.path.dirname(target_filename))
0103                 print ("Creating loader script for " + filename)
0104                 with open(target_filename, 'w') as f:
0105                     f.write(file_contents.format(module, filename))
0106             else:
0107                 print ("No pretty-printer module available for " + filename)
0108