#!/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> ...]
# ----------------------------------------------------------------------
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:])