| #!/usr/bin/env python |
| |
| #---------------------------------------------------------------------- |
| # 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> ...] |
| #---------------------------------------------------------------------- |
| from __future__ import print_function |
| |
| 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:]) |