Revert "[testsuite] Port crashlog and dependencies to Python 3."

This revert the commit because it broke the bots. I need to find
a way that works with both versions.

llvm-svn: 355364
This commit is contained in:
Davide Italiano 2019-03-05 01:34:47 +00:00
parent ff4bb36d7c
commit 814ad73452
3 changed files with 117 additions and 130 deletions

View File

@ -8,12 +8,8 @@
# (lldb) script import lldb.macosx.heap # (lldb) script import lldb.macosx.heap
#---------------------------------------------------------------------- #----------------------------------------------------------------------
from __future__ import print_function
from builtins import str
from builtins import hex
from builtins import range
import lldb import lldb
import subprocess import commands
import optparse import optparse
import os import os
import os.path import os.path
@ -232,7 +228,7 @@ def append_regex_callback(option, opt, value, parser):
ivar_regex = re.compile(value) ivar_regex = re.compile(value)
parser.values.ivar_regex_blacklist.append(ivar_regex) parser.values.ivar_regex_blacklist.append(ivar_regex)
except: except:
print('error: an exception was thrown when compiling the ivar regular expression for "%s"' % value) print 'error: an exception was thrown when compiling the ivar regular expression for "%s"' % value
def add_common_options(parser): def add_common_options(parser):
@ -393,16 +389,16 @@ def find_variable_containing_address(verbose, frame, match_addr):
if var_addr != lldb.LLDB_INVALID_ADDRESS: if var_addr != lldb.LLDB_INVALID_ADDRESS:
byte_size = var.GetType().GetByteSize() byte_size = var.GetType().GetByteSize()
if verbose: if verbose:
print('frame #%u: [%#x - %#x) %s' % (frame.GetFrameID(), var.load_addr, var.load_addr + byte_size, var.name)) print 'frame #%u: [%#x - %#x) %s' % (frame.GetFrameID(), var.load_addr, var.load_addr + byte_size, var.name)
if var_addr == match_addr: if var_addr == match_addr:
if verbose: if verbose:
print('match') print 'match'
return var return var
else: else:
if byte_size > 0 and var_addr <= match_addr and match_addr < ( if byte_size > 0 and var_addr <= match_addr and match_addr < (
var_addr + byte_size): var_addr + byte_size):
if verbose: if verbose:
print('match') print 'match'
return var return var
return None return None
@ -620,10 +616,10 @@ lldb_info''' % (options.max_frames, options.max_history, addr)
expr_options.SetPrefix(expr_prefix) expr_options.SetPrefix(expr_prefix)
expr_sbvalue = frame.EvaluateExpression(expr, expr_options) expr_sbvalue = frame.EvaluateExpression(expr, expr_options)
if options.verbose: if options.verbose:
print("expression:") print "expression:"
print(expr) print expr
print("expression result:") print "expression result:"
print(expr_sbvalue) print expr_sbvalue
if expr_sbvalue.error.Success(): if expr_sbvalue.error.Success():
if history: if history:
malloc_stack_history = lldb.value(expr_sbvalue) malloc_stack_history = lldb.value(expr_sbvalue)
@ -674,10 +670,10 @@ def display_match_results(
expr_options.SetPrefix(expr_prefix) expr_options.SetPrefix(expr_prefix)
expr_sbvalue = frame.EvaluateExpression(expr, expr_options) expr_sbvalue = frame.EvaluateExpression(expr, expr_options)
if options.verbose: if options.verbose:
print("expression:") print "expression:"
print(expr) print expr
print("expression result:") print "expression result:"
print(expr_sbvalue) print expr_sbvalue
if expr_sbvalue.error.Success(): if expr_sbvalue.error.Success():
match_value = lldb.value(expr_sbvalue) match_value = lldb.value(expr_sbvalue)
i = 0 i = 0
@ -867,14 +863,14 @@ def find_variable(debugger, command, result, dict):
for arg in args: for arg in args:
var_addr = int(arg, 16) var_addr = int(arg, 16)
print("Finding a variable with address %#x..." % (var_addr), file=result) print >>result, "Finding a variable with address %#x..." % (var_addr)
done = False done = False
for thread in process: for thread in process:
for frame in thread: for frame in thread:
var = find_variable_containing_address( var = find_variable_containing_address(
options.verbose, frame, var_addr) options.verbose, frame, var_addr)
if var: if var:
print(var) print var
done = True done = True
break break
if done: if done:
@ -1523,4 +1519,4 @@ lldb.debugger.HandleCommand(
lldb.debugger.HandleCommand( lldb.debugger.HandleCommand(
'command script add -f %s.objc_refs objc_refs' % 'command script add -f %s.objc_refs objc_refs' %
__name__) __name__)
print('"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.') print '"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.'

View File

@ -26,12 +26,7 @@
# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash # PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
#---------------------------------------------------------------------- #----------------------------------------------------------------------
from __future__ import print_function import commands
from builtins import str
from builtins import map
from builtins import range
from builtins import object
import subprocess
import cmd import cmd
import datetime import datetime
import glob import glob
@ -56,7 +51,7 @@ except ImportError:
platform_system = platform.system() platform_system = platform.system()
if platform_system == 'Darwin': if platform_system == 'Darwin':
# On Darwin, try the currently selected Xcode directory # On Darwin, try the currently selected Xcode directory
xcode_dir = subprocess.getoutput("xcode-select --print-path") xcode_dir = commands.getoutput("xcode-select --print-path")
if xcode_dir: if xcode_dir:
lldb_python_dirs.append( lldb_python_dirs.append(
os.path.realpath( os.path.realpath(
@ -76,11 +71,11 @@ except ImportError:
except ImportError: except ImportError:
pass pass
else: else:
print('imported lldb from: "%s"' % (lldb_python_dir)) print 'imported lldb from: "%s"' % (lldb_python_dir)
success = True success = True
break break
if not success: if not success:
print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly") print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
sys.exit(1) sys.exit(1)
from lldb.utils import symbolication from lldb.utils import symbolication
@ -104,7 +99,7 @@ class CrashLog(symbolication.Symbolicator):
'(0x[0-9a-fA-F]+)[-\s]+(0x[0-9a-fA-F]+)\s+[+]?(.+?)\s+(\(.+\))?\s?(<([-0-9a-fA-F]+)>)? (.*)') '(0x[0-9a-fA-F]+)[-\s]+(0x[0-9a-fA-F]+)\s+[+]?(.+?)\s+(\(.+\))?\s?(<([-0-9a-fA-F]+)>)? (.*)')
empty_line_regex = re.compile('^$') empty_line_regex = re.compile('^$')
class Thread(object): class Thread:
"""Class that represents a thread in a darwin crash log""" """Class that represents a thread in a darwin crash log"""
def __init__(self, index, app_specific_backtrace): def __init__(self, index, app_specific_backtrace):
@ -118,17 +113,17 @@ class CrashLog(symbolication.Symbolicator):
def dump(self, prefix): def dump(self, prefix):
if self.app_specific_backtrace: if self.app_specific_backtrace:
print("%Application Specific Backtrace[%u] %s" % (prefix, self.index, self.reason)) print "%Application Specific Backtrace[%u] %s" % (prefix, self.index, self.reason)
else: else:
print("%sThread[%u] %s" % (prefix, self.index, self.reason)) print "%sThread[%u] %s" % (prefix, self.index, self.reason)
if self.frames: if self.frames:
print("%s Frames:" % (prefix)) print "%s Frames:" % (prefix)
for frame in self.frames: for frame in self.frames:
frame.dump(prefix + ' ') frame.dump(prefix + ' ')
if self.registers: if self.registers:
print("%s Registers:" % (prefix)) print "%s Registers:" % (prefix)
for reg in list(self.registers.keys()): for reg in self.registers.keys():
print("%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg])) print "%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg])
def dump_symbolicated(self, crash_log, options): def dump_symbolicated(self, crash_log, options):
this_thread_crashed = self.app_specific_backtrace this_thread_crashed = self.app_specific_backtrace
@ -137,7 +132,7 @@ class CrashLog(symbolication.Symbolicator):
if options.crashed_only and this_thread_crashed == False: if options.crashed_only and this_thread_crashed == False:
return return
print("%s" % self) print "%s" % self
#prev_frame_index = -1 #prev_frame_index = -1
display_frame_idx = -1 display_frame_idx = -1
for frame_idx, frame in enumerate(self.frames): for frame_idx, frame in enumerate(self.frames):
@ -156,7 +151,7 @@ class CrashLog(symbolication.Symbolicator):
symbolicated_frame_address_idx = 0 symbolicated_frame_address_idx = 0
for symbolicated_frame_address in symbolicated_frame_addresses: for symbolicated_frame_address in symbolicated_frame_addresses:
display_frame_idx += 1 display_frame_idx += 1
print('[%3u] %s' % (frame_idx, symbolicated_frame_address)) print '[%3u] %s' % (frame_idx, symbolicated_frame_address)
if (options.source_all or self.did_crash( if (options.source_all or self.did_crash(
)) and display_frame_idx < options.source_frames and options.source_context: )) and display_frame_idx < options.source_frames and options.source_context:
source_context = options.source_context source_context = options.source_context
@ -171,12 +166,12 @@ class CrashLog(symbolication.Symbolicator):
# Indent the source a bit # Indent the source a bit
indent_str = ' ' indent_str = ' '
join_str = '\n' + indent_str join_str = '\n' + indent_str
print('%s%s' % (indent_str, join_str.join(source_text.split('\n')))) print '%s%s' % (indent_str, join_str.join(source_text.split('\n')))
if symbolicated_frame_address_idx == 0: if symbolicated_frame_address_idx == 0:
if disassemble: if disassemble:
instructions = symbolicated_frame_address.get_instructions() instructions = symbolicated_frame_address.get_instructions()
if instructions: if instructions:
print() print
symbolication.disassemble_instructions( symbolication.disassemble_instructions(
crash_log.get_target(), crash_log.get_target(),
instructions, instructions,
@ -184,10 +179,10 @@ class CrashLog(symbolication.Symbolicator):
options.disassemble_before, options.disassemble_before,
options.disassemble_after, options.disassemble_after,
frame.index > 0) frame.index > 0)
print() print
symbolicated_frame_address_idx += 1 symbolicated_frame_address_idx += 1
else: else:
print(frame) print frame
def add_ident(self, ident): def add_ident(self, ident):
if ident not in self.idents: if ident not in self.idents:
@ -205,7 +200,7 @@ class CrashLog(symbolication.Symbolicator):
s += ' %s' % self.reason s += ' %s' % self.reason
return s return s
class Frame(object): class Frame:
"""Class that represents a stack frame in a thread in a darwin crash log""" """Class that represents a stack frame in a thread in a darwin crash log"""
def __init__(self, index, pc, description): def __init__(self, index, pc, description):
@ -221,13 +216,13 @@ class CrashLog(symbolication.Symbolicator):
return "[%3u] 0x%16.16x" % (self.index, self.pc) return "[%3u] 0x%16.16x" % (self.index, self.pc)
def dump(self, prefix): def dump(self, prefix):
print("%s%s" % (prefix, str(self))) print "%s%s" % (prefix, str(self))
class DarwinImage(symbolication.Image): class DarwinImage(symbolication.Image):
"""Class that represents a binary images in a darwin crash log""" """Class that represents a binary images in a darwin crash log"""
dsymForUUIDBinary = os.path.expanduser('~rc/bin/dsymForUUID') dsymForUUIDBinary = os.path.expanduser('~rc/bin/dsymForUUID')
if not os.path.exists(dsymForUUIDBinary): if not os.path.exists(dsymForUUIDBinary):
dsymForUUIDBinary = subprocess.getoutput('which dsymForUUID') dsymForUUIDBinary = commands.getoutput('which dsymForUUID')
dwarfdump_uuid_regex = re.compile( dwarfdump_uuid_regex = re.compile(
'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
@ -250,7 +245,7 @@ class CrashLog(symbolication.Symbolicator):
self.version = version self.version = version
def find_matching_slice(self): def find_matching_slice(self):
dwarfdump_cmd_output = subprocess.getoutput( dwarfdump_cmd_output = commands.getoutput(
'dwarfdump --uuid "%s"' % self.path) 'dwarfdump --uuid "%s"' % self.path)
self_uuid = self.get_uuid() self_uuid = self.get_uuid()
for line in dwarfdump_cmd_output.splitlines(): for line in dwarfdump_cmd_output.splitlines():
@ -275,16 +270,16 @@ class CrashLog(symbolication.Symbolicator):
# Mark this as resolved so we don't keep trying # Mark this as resolved so we don't keep trying
self.resolved = True self.resolved = True
uuid_str = self.get_normalized_uuid_string() uuid_str = self.get_normalized_uuid_string()
print('Getting symbols for %s %s...' % (uuid_str, self.path), end=' ') print 'Getting symbols for %s %s...' % (uuid_str, self.path),
if os.path.exists(self.dsymForUUIDBinary): if os.path.exists(self.dsymForUUIDBinary):
dsym_for_uuid_command = '%s %s' % ( dsym_for_uuid_command = '%s %s' % (
self.dsymForUUIDBinary, uuid_str) self.dsymForUUIDBinary, uuid_str)
s = subprocess.getoutput(dsym_for_uuid_command) s = commands.getoutput(dsym_for_uuid_command)
if s: if s:
try: try:
plist_root = plistlib.readPlistFromString(s) plist_root = plistlib.readPlistFromString(s)
except: except:
print(("Got exception: ", sys.exc_info()[1], " handling dsymForUUID output: \n", s)) print("Got exception: ", sys.exc_value, " handling dsymForUUID output: \n", s)
raise raise
if plist_root: if plist_root:
plist = plist_root[uuid_str] plist = plist_root[uuid_str]
@ -320,7 +315,7 @@ class CrashLog(symbolication.Symbolicator):
pass pass
if (self.resolved_path and os.path.exists(self.resolved_path)) or ( if (self.resolved_path and os.path.exists(self.resolved_path)) or (
self.path and os.path.exists(self.path)): self.path and os.path.exists(self.path)):
print('ok') print 'ok'
# if self.resolved_path: # if self.resolved_path:
# print ' exe = "%s"' % self.resolved_path # print ' exe = "%s"' % self.resolved_path
# if self.symfile: # if self.symfile:
@ -476,7 +471,7 @@ class CrashLog(symbolication.Symbolicator):
thread.frames.append(CrashLog.Frame(int(frame_match.group(1)), int( thread.frames.append(CrashLog.Frame(int(frame_match.group(1)), int(
frame_match.group(3), 0), frame_match.group(4))) frame_match.group(3), 0), frame_match.group(4)))
else: else:
print('error: frame regex failed for line: "%s"' % line) print 'error: frame regex failed for line: "%s"' % line
elif parse_mode == PARSE_MODE_IMAGES: elif parse_mode == PARSE_MODE_IMAGES:
image_match = self.image_regex_uuid.search(line) image_match = self.image_regex_uuid.search(line)
if image_match: if image_match:
@ -489,7 +484,7 @@ class CrashLog(symbolication.Symbolicator):
uuid.UUID(img_uuid), img_path) uuid.UUID(img_uuid), img_path)
self.images.append(image) self.images.append(image)
else: else:
print("error: image regex failed for: %s" % line) print "error: image regex failed for: %s" % line
elif parse_mode == PARSE_MODE_THREGS: elif parse_mode == PARSE_MODE_THREGS:
stripped_line = line.strip() stripped_line = line.strip()
@ -507,15 +502,15 @@ class CrashLog(symbolication.Symbolicator):
f.close() f.close()
def dump(self): def dump(self):
print("Crash Log File: %s" % (self.path)) print "Crash Log File: %s" % (self.path)
if self.backtraces: if self.backtraces:
print("\nApplication Specific Backtraces:") print "\nApplication Specific Backtraces:"
for thread in self.backtraces: for thread in self.backtraces:
thread.dump(' ') thread.dump(' ')
print("\nThreads:") print "\nThreads:"
for thread in self.threads: for thread in self.threads:
thread.dump(' ') thread.dump(' ')
print("\nImages:") print "\nImages:"
for image in self.images: for image in self.images:
image.dump(' ') image.dump(' ')
@ -538,7 +533,7 @@ class CrashLog(symbolication.Symbolicator):
return self.target return self.target
# We weren't able to open the main executable as, but we can still # We weren't able to open the main executable as, but we can still
# symbolicate # symbolicate
print('crashlog.create_target()...2') print 'crashlog.create_target()...2'
if self.idents: if self.idents:
for ident in self.idents: for ident in self.idents:
image = self.find_image_with_identifier(ident) image = self.find_image_with_identifier(ident)
@ -546,13 +541,13 @@ class CrashLog(symbolication.Symbolicator):
self.target = image.create_target() self.target = image.create_target()
if self.target: if self.target:
return self.target # success return self.target # success
print('crashlog.create_target()...3') print 'crashlog.create_target()...3'
for image in self.images: for image in self.images:
self.target = image.create_target() self.target = image.create_target()
if self.target: if self.target:
return self.target # success return self.target # success
print('crashlog.create_target()...4') print 'crashlog.create_target()...4'
print('error: unable to locate any executables from the crash log') print 'error: unable to locate any executables from the crash log'
return self.target return self.target
def get_target(self): def get_target(self):
@ -560,7 +555,7 @@ class CrashLog(symbolication.Symbolicator):
def usage(): def usage():
print("Usage: lldb-symbolicate.py [-n name] executable-image") print "Usage: lldb-symbolicate.py [-n name] executable-image"
sys.exit(0) sys.exit(0)
@ -577,7 +572,7 @@ class Interactive(cmd.Cmd):
def default(self, line): def default(self, line):
'''Catch all for unknown command, which will exit the interpreter.''' '''Catch all for unknown command, which will exit the interpreter.'''
print("uknown command: %s" % line) print "uknown command: %s" % line
return True return True
def do_q(self, line): def do_q(self, line):
@ -607,7 +602,7 @@ class Interactive(cmd.Cmd):
if idx < len(self.crash_logs): if idx < len(self.crash_logs):
SymbolicateCrashLog(self.crash_logs[idx], options) SymbolicateCrashLog(self.crash_logs[idx], options)
else: else:
print('error: crash log index %u is out of range' % (idx)) print 'error: crash log index %u is out of range' % (idx)
else: else:
# No arguments, symbolicate all crash logs using the options # No arguments, symbolicate all crash logs using the options
# provided # provided
@ -618,9 +613,9 @@ class Interactive(cmd.Cmd):
'''Dump a list of all crash logs that are currently loaded. '''Dump a list of all crash logs that are currently loaded.
USAGE: list''' USAGE: list'''
print('%u crash logs are loaded:' % len(self.crash_logs)) print '%u crash logs are loaded:' % len(self.crash_logs)
for (crash_log_idx, crash_log) in enumerate(self.crash_logs): for (crash_log_idx, crash_log) in enumerate(self.crash_logs):
print('[%u] = %s' % (crash_log_idx, crash_log.path)) print '[%u] = %s' % (crash_log_idx, crash_log.path)
def do_image(self, line): def do_image(self, line):
'''Dump information about one or more binary images in the crash log given an image basename, or all images if no arguments are provided.''' '''Dump information about one or more binary images in the crash log given an image basename, or all images if no arguments are provided.'''
@ -650,22 +645,22 @@ class Interactive(cmd.Cmd):
if fullpath_search: if fullpath_search:
if image.get_resolved_path() == image_path: if image.get_resolved_path() == image_path:
matches_found += 1 matches_found += 1
print('[%u] ' % (crash_log_idx), image) print '[%u] ' % (crash_log_idx), image
else: else:
image_basename = image.get_resolved_path_basename() image_basename = image.get_resolved_path_basename()
if image_basename == image_path: if image_basename == image_path:
matches_found += 1 matches_found += 1
print('[%u] ' % (crash_log_idx), image) print '[%u] ' % (crash_log_idx), image
if matches_found == 0: if matches_found == 0:
for (image_idx, image) in enumerate(crash_log.images): for (image_idx, image) in enumerate(crash_log.images):
resolved_image_path = image.get_resolved_path() resolved_image_path = image.get_resolved_path()
if resolved_image_path and string.find( if resolved_image_path and string.find(
image.get_resolved_path(), image_path) >= 0: image.get_resolved_path(), image_path) >= 0:
print('[%u] ' % (crash_log_idx), image) print '[%u] ' % (crash_log_idx), image
else: else:
for crash_log in self.crash_logs: for crash_log in self.crash_logs:
for (image_idx, image) in enumerate(crash_log.images): for (image_idx, image) in enumerate(crash_log.images):
print('[%u] %s' % (image_idx, image)) print '[%u] %s' % (image_idx, image)
return False return False
@ -680,12 +675,12 @@ def interactive_crashlogs(options, args):
# print 'crash_log_file = "%s"' % crash_log_file # print 'crash_log_file = "%s"' % crash_log_file
crash_log = CrashLog(crash_log_file) crash_log = CrashLog(crash_log_file)
if crash_log.error: if crash_log.error:
print(crash_log.error) print crash_log.error
continue continue
if options.debug: if options.debug:
crash_log.dump() crash_log.dump()
if not crash_log.images: if not crash_log.images:
print('error: no images in crash log "%s"' % (crash_log)) print 'error: no images in crash log "%s"' % (crash_log)
continue continue
else: else:
crash_logs.append(crash_log) crash_logs.append(crash_log)
@ -741,7 +736,7 @@ def save_crashlog(debugger, command, exe_ctx, result, dict):
(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
out_file.write( out_file.write(
'OS Version: Mac OS X %s (%s)\n' % 'OS Version: Mac OS X %s (%s)\n' %
(platform.mac_ver()[0], subprocess.getoutput('sysctl -n kern.osversion'))) (platform.mac_ver()[0], commands.getoutput('sysctl -n kern.osversion')))
out_file.write('Report Version: 9\n') out_file.write('Report Version: 9\n')
for thread_idx in range(process.num_threads): for thread_idx in range(process.num_threads):
thread = process.thread[thread_idx] thread = process.thread[thread_idx]
@ -813,21 +808,21 @@ def Symbolicate(debugger, command, result, dict):
def SymbolicateCrashLog(crash_log, options): def SymbolicateCrashLog(crash_log, options):
if crash_log.error: if crash_log.error:
print(crash_log.error) print crash_log.error
return return
if options.debug: if options.debug:
crash_log.dump() crash_log.dump()
if not crash_log.images: if not crash_log.images:
print('error: no images in crash log') print 'error: no images in crash log'
return return
if options.dump_image_list: if options.dump_image_list:
print("Binary Images:") print "Binary Images:"
for image in crash_log.images: for image in crash_log.images:
if options.verbose: if options.verbose:
print(image.debug_dump()) print image.debug_dump()
else: else:
print(image) print image
target = crash_log.create_target() target = crash_log.create_target()
if not target: if not target:
@ -850,7 +845,7 @@ def SymbolicateCrashLog(crash_log, options):
for image in images: for image in images:
images_to_load.append(image) images_to_load.append(image)
else: else:
print('error: can\'t find image for identifier "%s"' % ident) print 'error: can\'t find image for identifier "%s"' % ident
else: else:
for ident in crash_log.idents: for ident in crash_log.idents:
images = crash_log.find_images_with_identifier(ident) images = crash_log.find_images_with_identifier(ident)
@ -858,13 +853,13 @@ def SymbolicateCrashLog(crash_log, options):
for image in images: for image in images:
images_to_load.append(image) images_to_load.append(image)
else: else:
print('error: can\'t find image for identifier "%s"' % ident) print 'error: can\'t find image for identifier "%s"' % ident
for image in images_to_load: for image in images_to_load:
if image not in loaded_images: if image not in loaded_images:
err = image.add_module(target) err = image.add_module(target)
if err: if err:
print(err) print err
else: else:
# print 'loaded %s' % image # print 'loaded %s' % image
loaded_images.append(image) loaded_images.append(image)
@ -872,11 +867,11 @@ def SymbolicateCrashLog(crash_log, options):
if crash_log.backtraces: if crash_log.backtraces:
for thread in crash_log.backtraces: for thread in crash_log.backtraces:
thread.dump_symbolicated(crash_log, options) thread.dump_symbolicated(crash_log, options)
print() print
for thread in crash_log.threads: for thread in crash_log.threads:
thread.dump_symbolicated(crash_log, options) thread.dump_symbolicated(crash_log, options)
print() print
def CreateSymbolicateCrashLogOptions( def CreateSymbolicateCrashLogOptions(
@ -1003,12 +998,12 @@ be disassembled and lookups can be performed using the addresses found in the cr
return return
if options.debug: if options.debug:
print('command_args = %s' % command_args) print 'command_args = %s' % command_args
print('options', options) print 'options', options
print('args', args) print 'args', args
if options.debug_delay > 0: if options.debug_delay > 0:
print("Waiting %u seconds for debugger to attach..." % options.debug_delay) print "Waiting %u seconds for debugger to attach..." % options.debug_delay
time.sleep(options.debug_delay) time.sleep(options.debug_delay)
error = lldb.SBError() error = lldb.SBError()
@ -1029,4 +1024,4 @@ elif getattr(lldb, 'debugger', None):
'command script add -f lldb.macosx.crashlog.Symbolicate crashlog') 'command script add -f lldb.macosx.crashlog.Symbolicate crashlog')
lldb.debugger.HandleCommand( lldb.debugger.HandleCommand(
'command script add -f lldb.macosx.crashlog.save_crashlog save_crashlog') 'command script add -f lldb.macosx.crashlog.save_crashlog save_crashlog')
print('"crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help') print '"crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help'

View File

@ -26,12 +26,8 @@
# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash # PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
#---------------------------------------------------------------------- #----------------------------------------------------------------------
from __future__ import print_function
from builtins import str
from builtins import range
from builtins import object
import lldb import lldb
import subprocess import commands
import optparse import optparse
import os import os
import plistlib import plistlib
@ -42,7 +38,7 @@ import time
import uuid import uuid
class Address(object): class Address:
"""Class that represents an address that will be symbolicated""" """Class that represents an address that will be symbolicated"""
def __init__(self, target, load_addr): def __init__(self, target, load_addr):
@ -160,7 +156,7 @@ class Address(object):
return False return False
class Section(object): class Section:
"""Class that represents an load address range""" """Class that represents an load address range"""
sect_info_regex = re.compile('(?P<name>[^=]+)=(?P<range>.*)') sect_info_regex = re.compile('(?P<name>[^=]+)=(?P<range>.*)')
addr_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*$') addr_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*$')
@ -207,13 +203,13 @@ class Section(object):
if op == '+': if op == '+':
self.end_addr += self.start_addr self.end_addr += self.start_addr
return True return True
print('error: invalid section info string "%s"' % s) print 'error: invalid section info string "%s"' % s
print('Valid section info formats are:') print 'Valid section info formats are:'
print('Format Example Description') print 'Format Example Description'
print('--------------------- -----------------------------------------------') print '--------------------- -----------------------------------------------'
print('<name>=<base> __TEXT=0x123000 Section from base address only') print '<name>=<base> __TEXT=0x123000 Section from base address only'
print('<name>=<base>-<end> __TEXT=0x123000-0x124000 Section from base address and end address') print '<name>=<base>-<end> __TEXT=0x123000-0x124000 Section from base address and end address'
print('<name>=<base>+<size> __TEXT=0x123000+0x1000 Section from base address and size') print '<name>=<base>+<size> __TEXT=0x123000+0x1000 Section from base address and size'
return False return False
def __str__(self): def __str__(self):
@ -229,7 +225,7 @@ class Section(object):
return "<invalid>" return "<invalid>"
class Image(object): class Image:
"""A class that represents an executable image and any associated data""" """A class that represents an executable image and any associated data"""
def __init__(self, path, uuid=None): def __init__(self, path, uuid=None):
@ -265,21 +261,21 @@ class Image(object):
return obj return obj
def dump(self, prefix): def dump(self, prefix):
print("%s%s" % (prefix, self)) print "%s%s" % (prefix, self)
def debug_dump(self): def debug_dump(self):
print('path = "%s"' % (self.path)) print 'path = "%s"' % (self.path)
print('resolved_path = "%s"' % (self.resolved_path)) print 'resolved_path = "%s"' % (self.resolved_path)
print('resolved = %i' % (self.resolved)) print 'resolved = %i' % (self.resolved)
print('unavailable = %i' % (self.unavailable)) print 'unavailable = %i' % (self.unavailable)
print('uuid = %s' % (self.uuid)) print 'uuid = %s' % (self.uuid)
print('section_infos = %s' % (self.section_infos)) print 'section_infos = %s' % (self.section_infos)
print('identifier = "%s"' % (self.identifier)) print 'identifier = "%s"' % (self.identifier)
print('version = %s' % (self.version)) print 'version = %s' % (self.version)
print('arch = %s' % (self.arch)) print 'arch = %s' % (self.arch)
print('module = %s' % (self.module)) print 'module = %s' % (self.module)
print('symfile = "%s"' % (self.symfile)) print 'symfile = "%s"' % (self.symfile)
print('slide = %i (0x%x)' % (self.slide, self.slide)) print 'slide = %i (0x%x)' % (self.slide, self.slide)
def __str__(self): def __str__(self):
s = '' s = ''
@ -432,16 +428,16 @@ class Image(object):
if self.has_section_load_info(): if self.has_section_load_info():
err = self.load_module(target) err = self.load_module(target)
if err: if err:
print('ERROR: ', err) print 'ERROR: ', err
return target return target
else: else:
print('error: unable to create a valid target for (%s) "%s"' % (self.arch, self.path)) print 'error: unable to create a valid target for (%s) "%s"' % (self.arch, self.path)
else: else:
print('error: unable to locate main executable (%s) "%s"' % (self.arch, self.path)) print 'error: unable to locate main executable (%s) "%s"' % (self.arch, self.path)
return None return None
class Symbolicator(object): class Symbolicator:
def __init__(self): def __init__(self):
"""A class the represents the information needed to symbolicate addresses in a program""" """A class the represents the information needed to symbolicate addresses in a program"""
@ -558,7 +554,7 @@ class Symbolicator(object):
if symbolicated_addresses: if symbolicated_addresses:
return symbolicated_addresses return symbolicated_addresses
else: else:
print('error: no target in Symbolicator') print 'error: no target in Symbolicator'
return None return None
@ -606,22 +602,22 @@ def disassemble_instructions(
end_idx = inst_idx end_idx = inst_idx
for i in range(start_idx, end_idx + 1): for i in range(start_idx, end_idx + 1):
if i == pc_index: if i == pc_index:
print(' -> ', lines[i]) print ' -> ', lines[i]
else: else:
print(' ', lines[i]) print ' ', lines[i]
def print_module_section_data(section): def print_module_section_data(section):
print(section) print section
section_data = section.GetSectionData() section_data = section.GetSectionData()
if section_data: if section_data:
ostream = lldb.SBStream() ostream = lldb.SBStream()
section_data.GetDescription(ostream, section.GetFileAddress()) section_data.GetDescription(ostream, section.GetFileAddress())
print(ostream.GetData()) print ostream.GetData()
def print_module_section(section, depth): def print_module_section(section, depth):
print(section) print section
if depth > 0: if depth > 0:
num_sub_sections = section.GetNumSubSections() num_sub_sections = section.GetNumSubSections()
for sect_idx in range(num_sub_sections): for sect_idx in range(num_sub_sections):
@ -636,7 +632,7 @@ def print_module_sections(module, depth):
def print_module_symbols(module): def print_module_symbols(module):
for sym in module: for sym in module:
print(sym) print sym
def Symbolicate(command_args): def Symbolicate(command_args):
@ -713,17 +709,17 @@ def Symbolicate(command_args):
target = symbolicator.create_target() target = symbolicator.create_target()
if options.verbose: if options.verbose:
print(symbolicator) print symbolicator
if target: if target:
for addr_str in args: for addr_str in args:
addr = int(addr_str, 0) addr = int(addr_str, 0)
symbolicated_addrs = symbolicator.symbolicate( symbolicated_addrs = symbolicator.symbolicate(
addr, options.verbose) addr, options.verbose)
for symbolicated_addr in symbolicated_addrs: for symbolicated_addr in symbolicated_addrs:
print(symbolicated_addr) print symbolicated_addr
print() print
else: else:
print('error: no target for %s' % (symbolicator)) print 'error: no target for %s' % (symbolicator)
if __name__ == '__main__': if __name__ == '__main__':
# Create a new debugger instance # Create a new debugger instance