1#!/usr/bin/env python 2 3#---------------------------------------------------------------------- 4# For the shells csh, tcsh: 5# ( setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ; ./globals.py <path> [<path> ...]) 6# 7# For the shells sh, bash: 8# PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ./globals.py <path> [<path> ...] 9#---------------------------------------------------------------------- 10 11import lldb 12import optparse 13import os 14import shlex 15import sys 16 17 18def get_globals(raw_path, options): 19 error = lldb.SBError() 20 # Resolve the path if needed 21 path = os.path.expanduser(raw_path) 22 # Create a target using path + options 23 target = lldb.debugger.CreateTarget( 24 path, options.arch, options.platform, False, error) 25 if target: 26 # Get the executable module 27 module = target.module[target.executable.basename] 28 if module: 29 # Keep track of which variables we have already looked up 30 global_names = list() 31 # Iterate through all symbols in the symbol table and watch for any 32 # DATA symbols 33 for symbol in module.symbols: 34 if symbol.type == lldb.eSymbolTypeData: 35 # The symbol is a DATA symbol, lets try and find all global variables 36 # that match this name and print them 37 global_name = symbol.name 38 # Make sure we don't lookup the same variable twice 39 if global_name not in global_names: 40 global_names.append(global_name) 41 # Find all global variables by name 42 global_variable_list = module.FindGlobalVariables( 43 target, global_name, lldb.UINT32_MAX) 44 if global_variable_list: 45 # Print results for anything that matched 46 for global_variable in global_variable_list: 47 # returns the global variable name as a string 48 print('name = %s' % global_variable.name) 49 # Returns the variable value as a string 50 print('value = %s' % global_variable.value) 51 print('type = %s' % global_variable.type) # Returns an lldb.SBType object 52 # Returns an lldb.SBAddress (section offset 53 # address) for this global 54 print('addr = %s' % global_variable.addr) 55 # Returns the file virtual address for this 56 # global 57 print('file_addr = 0x%x' % global_variable.addr.file_addr) 58 # returns the global variable value as a string 59 print('location = %s' % global_variable.location) 60 # Returns the size in bytes of this global 61 # variable 62 print('size = %s' % global_variable.size) 63 print() 64 65 66def globals(command_args): 67 '''Extract all globals from any arguments which must be paths to object files.''' 68 usage = "usage: %prog [options] <PATH> [PATH ...]" 69 description = '''This command will find all globals in the specified object file and return an list() of lldb.SBValue objects (which might be empty).''' 70 parser = optparse.OptionParser( 71 description=description, 72 prog='globals', 73 usage=usage) 74 parser.add_option( 75 '-v', 76 '--verbose', 77 action='store_true', 78 dest='verbose', 79 help='display verbose debug info', 80 default=False) 81 parser.add_option( 82 '-a', 83 '--arch', 84 type='string', 85 metavar='arch', 86 dest='arch', 87 help='Specify an architecture (or triple) to use when extracting from a file.') 88 parser.add_option( 89 '-p', 90 '--platform', 91 type='string', 92 metavar='platform', 93 dest='platform', 94 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".') 95 try: 96 (options, args) = parser.parse_args(command_args) 97 except: 98 return 99 100 for path in args: 101 get_globals(path, options) 102 103if __name__ == '__main__': 104 lldb.debugger = lldb.SBDebugger.Create() 105 globals(sys.argv[1:]) 106