| #!/usr/bin/env python3 | |
| # ---------------------------------------------------------------------- | |
| # For the shells csh, tcsh: | |
| # ( setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ; ./globals.py <path> [<path> ...]) | |
| # | |
| # For the shells sh, bash: | |
| # PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ./globals.py <path> [<path> ...] | |
| # ---------------------------------------------------------------------- | |
| import lldb | |
| import optparse | |
| import os | |
| import shlex | |
| import sys | |
| def get_globals(raw_path, options): | |
| error = lldb.SBError() | |
| # Resolve the path if needed | |
| path = os.path.expanduser(raw_path) | |
| # Create a target using path + options | |
| target = lldb.debugger.CreateTarget( | |
| path, options.arch, options.platform, False, error | |
| ) | |
| if target: | |
| # Get the executable module | |
| module = target.module[target.executable.basename] | |
| if module: | |
| # Keep track of which variables we have already looked up | |
| global_names = list() | |
| # Iterate through all symbols in the symbol table and watch for any | |
| # DATA symbols | |
| for symbol in module.symbols: | |
| if symbol.type == lldb.eSymbolTypeData: | |
| # The symbol is a DATA symbol, lets try and find all global variables | |
| # that match this name and print them | |
| global_name = symbol.name | |
| # Make sure we don't lookup the same variable twice | |
| if global_name not in global_names: | |
| global_names.append(global_name) | |
| # Find all global variables by name | |
| global_variable_list = module.FindGlobalVariables( | |
| target, global_name, lldb.UINT32_MAX | |
| ) | |
| if global_variable_list: | |
| # Print results for anything that matched | |
| for global_variable in global_variable_list: | |
| # returns the global variable name as a string | |
| print("name = %s" % global_variable.name) | |
| # Returns the variable value as a string | |
| print("value = %s" % global_variable.value) | |
| print( | |
| "type = %s" % global_variable.type | |
| ) # Returns an lldb.SBType object | |
| # Returns an lldb.SBAddress (section offset | |
| # address) for this global | |
| print("addr = %s" % global_variable.addr) | |
| # Returns the file virtual address for this | |
| # global | |
| print( | |
| "file_addr = 0x%x" % global_variable.addr.file_addr | |
| ) | |
| # returns the global variable value as a string | |
| print("location = %s" % global_variable.location) | |
| # Returns the size in bytes of this global | |
| # variable | |
| print("size = %s" % global_variable.size) | |
| print() | |
| def globals(command_args): | |
| """Extract all globals from any arguments which must be paths to object files.""" | |
| usage = "usage: %prog [options] <PATH> [PATH ...]" | |
| description = """This command will find all globals in the specified object file and return an list() of lldb.SBValue objects (which might be empty).""" | |
| parser = optparse.OptionParser(description=description, prog="globals", usage=usage) | |
| parser.add_option( | |
| "-v", | |
| "--verbose", | |
| action="store_true", | |
| dest="verbose", | |
| help="display verbose debug info", | |
| default=False, | |
| ) | |
| parser.add_option( | |
| "-a", | |
| "--arch", | |
| type="string", | |
| metavar="arch", | |
| dest="arch", | |
| help="Specify an architecture (or triple) to use when extracting from a file.", | |
| ) | |
| parser.add_option( | |
| "-p", | |
| "--platform", | |
| type="string", | |
| metavar="platform", | |
| dest="platform", | |
| help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".', | |
| ) | |
| try: | |
| (options, args) = parser.parse_args(command_args) | |
| except: | |
| return | |
| for path in args: | |
| get_globals(path, options) | |
| if __name__ == "__main__": | |
| lldb.debugger = lldb.SBDebugger.Create() | |
| globals(sys.argv[1:]) |