crashlog.py revision e9ee550693aee8122d3d48b633fcff64e6a2f641
101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton#!/usr/bin/python 201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton#---------------------------------------------------------------------- 401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton# Be sure to add the python path that points to the LLDB shared library. 501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton# On MacOSX csh, tcsh: 601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python 701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton# On MacOSX sh, bash: 801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python 901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton#---------------------------------------------------------------------- 1001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 1101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport lldb 1201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport commands # commands.getoutput ('/bin/ls /tmp') 1301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport optparse 1401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport os 1501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport plistlib 1601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport pprint 1701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport re 1801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport sys 1901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonimport time 20cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Claytonimport uuid 21cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton 2201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 2301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg ClaytonPARSE_MODE_NORMAL = 0 2401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg ClaytonPARSE_MODE_THREAD = 1 2501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg ClaytonPARSE_MODE_IMAGES = 2 2601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg ClaytonPARSE_MODE_THREGS = 3 2701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg ClaytonPARSE_MODE_SYSTEM = 4 2801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 2901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonclass CrashLog: 3001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton """Class that does parses darwin crash logs""" 3101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_state_regex = re.compile('^Thread ([0-9]+) crashed with') 3201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)') 338077a5334dc4daef3a145d07307a970d00563055Greg Clayton frame_regex = re.compile('^([0-9]+) +([^ ]+) *\t(0x[0-9a-fA-F]+) +(.*)') 348077a5334dc4daef3a145d07307a970d00563055Greg Clayton image_regex_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +[+]?([^ ]+) +([^<]+)<([-0-9a-fA-F]+)> (.*)'); 358077a5334dc4daef3a145d07307a970d00563055Greg Clayton image_regex_no_uuid = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +[+]?([^ ]+) +([^/]+)/(.*)'); 3601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton empty_line_regex = re.compile('^$') 3701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 3801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton class Thread: 3901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton """Class that represents a thread in a darwin crash log""" 4001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __init__(self, index): 4101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.index = index 4201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.frames = list() 4301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.registers = dict() 4401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.reason = None 4501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.queue = None 4601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 4701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def dump(self, prefix): 4801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%sThread[%u] %s" % (prefix, self.index, self.reason) 4901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.frames: 5001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s Frames:" % (prefix) 5101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for frame in self.frames: 5201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton frame.dump(prefix + ' ') 5301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.registers: 5401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s Registers:" % (prefix) 5501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for reg in self.registers.keys(): 5601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg]) 5701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 5801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def did_crash(self): 5901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return self.reason != None 6001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 6101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __str__(self): 6201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton s = "Thread[%u]" % self.index 6301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.reason: 6401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton s += ' %s' % self.reason 6501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return s 6601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 6701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 6801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton class Frame: 6901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton """Class that represents a stack frame in a thread in a darwin crash log""" 7001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __init__(self, index, pc, details): 7101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.index = index 7201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.pc = pc 7301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.sym_ctx = None 7401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.details = details 7501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 7601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __str__(self): 7701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return "[%2u] %#16.16x %s" % (self.index, self.pc, self.details) 7801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 7901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def dump(self, prefix): 8001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s%s" % (prefix, self) 8101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 8201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 8301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton class Image: 8401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton """Class that represents a binary images in a darwin crash log""" 858077a5334dc4daef3a145d07307a970d00563055Greg Clayton dsymForUUIDBinary = os.path.expanduser('~rc/bin/dsymForUUID') 86cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if not os.path.exists(dsymForUUIDBinary): 87cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton dsymForUUIDBinary = commands.getoutput('which dsymForUUID') 88cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton 89cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton dwarfdump_uuid_regex = re.compile('UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') 908077a5334dc4daef3a145d07307a970d00563055Greg Clayton 9101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __init__(self, text_addr_lo, text_addr_hi, ident, version, uuid, path): 9201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.text_addr_lo = text_addr_lo 9301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.text_addr_hi = text_addr_hi 9401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.ident = ident 9501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.version = version 96cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.arch = None 9701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.uuid = uuid 9801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.path = path 99cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.resolved_path = None 100cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.dsym = None 10101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.module = None 10201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 10301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def dump(self, prefix): 10401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s%s" % (prefix, self) 10501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 10601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __str__(self): 107cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return "%#16.16x %s %s" % (self.text_addr_lo, self.uuid, self.get_resolved_path()) 10801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 109cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton def get_resolved_path(self): 110cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self.resolved_path: 111cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return self.resolved_path 112cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton elif self.path: 113cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return self.path 114cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return None 115cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton 116cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton def get_resolved_path_basename(self): 117cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton path = self.get_resolved_path() 118cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if path: 119cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return os.path.basename(path) 120cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return None 121cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton 122cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton def dsym_basename(self): 123cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self.dsym: 124cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return os.path.basename(self.dsym) 12501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return None 12601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 12701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def fetch_symboled_executable_and_dsym(self): 128cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self.resolved_path: 129cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton # Don't load a module twice... 130cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 0 131cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton print 'Locating %s %s...' % (self.uuid, self.path), 1328077a5334dc4daef3a145d07307a970d00563055Greg Clayton if os.path.exists(self.dsymForUUIDBinary): 1338077a5334dc4daef3a145d07307a970d00563055Greg Clayton dsym_for_uuid_command = '%s %s' % (self.dsymForUUIDBinary, self.uuid) 1348077a5334dc4daef3a145d07307a970d00563055Greg Clayton s = commands.getoutput(dsym_for_uuid_command) 1358077a5334dc4daef3a145d07307a970d00563055Greg Clayton if s: 1368077a5334dc4daef3a145d07307a970d00563055Greg Clayton plist_root = plistlib.readPlistFromString (s) 1378077a5334dc4daef3a145d07307a970d00563055Greg Clayton if plist_root: 1388077a5334dc4daef3a145d07307a970d00563055Greg Clayton # pp = pprint.PrettyPrinter(indent=4) 1398077a5334dc4daef3a145d07307a970d00563055Greg Clayton # pp.pprint(plist_root) 140cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton plist = plist_root[self.uuid] 141cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if plist: 142cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if 'DBGArchitecture' in plist: 143cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.arch = plist['DBGArchitecture'] 144cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if 'DBGDSYMPath' in plist: 145cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.dsym = os.path.realpath(plist['DBGDSYMPath']) 146cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if 'DBGSymbolRichExecutable' in plist: 147cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.resolved_path = os.path.expanduser (plist['DBGSymbolRichExecutable']) 148cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if not self.resolved_path and os.path.exists(self.path): 149cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton dwarfdump_cmd_output = commands.getoutput('dwarfdump --uuid "%s"' % self.path) 150cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self_uuid = uuid.UUID(self.uuid) 151cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton for line in dwarfdump_cmd_output.splitlines(): 152cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton match = self.dwarfdump_uuid_regex.search (line) 153cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if match: 154cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton dwarf_uuid_str = match.group(1) 155cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton dwarf_uuid = uuid.UUID(dwarf_uuid_str) 156cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self_uuid == dwarf_uuid: 157cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.resolved_path = self.path 158cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton self.arch = match.group(2) 159cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton break; 160cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if not self.resolved_path: 161cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton print "error: file %s '%s' doesn't match the UUID in the installed file" % (self.uuid, self.path) 162cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 0 163cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if (self.resolved_path and os.path.exists(self.resolved_path)) or (self.path and os.path.exists(self.path)): 164cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton print 'ok' 165cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self.path != self.resolved_path: 166cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton print ' exe = "%s"' % self.resolved_path 167cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton if self.dsym: 168cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton print ' dsym = "%s"' % self.dsym 169cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 1 17001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 171cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 0 17201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 17301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def load_module(self): 174e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if not lldb.target: 175e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return 'error: no target' 17601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.module: 17701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton text_section = self.module.FindSection ("__TEXT") 17801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if text_section: 179e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton error = lldb.target.SetSectionLoadAddress (text_section, self.text_addr_lo) 18001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if error.Success(): 1818077a5334dc4daef3a145d07307a970d00563055Greg Clayton #print 'Success: loaded %s.__TEXT = 0x%x' % (self.basename(), self.text_addr_lo) 18201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return None 18301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 18401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return 'error: %s' % error.GetCString() 18501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 186cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 'error: unable to find "__TEXT" section in "%s"' % self.get_resolved_path() 18701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 18801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return 'error: invalid module' 18901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 190e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton def create_target(self): 19101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.fetch_symboled_executable_and_dsym (): 192cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton resolved_path = self.get_resolved_path(); 193cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton path_spec = lldb.SBFileSpec (resolved_path) 19401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton #result.PutCString ('plist[%s] = %s' % (uuid, self.plist)) 19501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton error = lldb.SBError() 196e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton lldb.target = lldb.debugger.CreateTarget (resolved_path, self.arch, None, False, error); 197e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if lldb.target: 198e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton self.module = lldb.target.FindModule (path_spec) 19901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.module: 20001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton err = self.load_module() 20101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if err: 20201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print err 20301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 20401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return None 20501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 206cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 'error: unable to get module for (%s) "%s"' % (self.arch, resolved_path) 20701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 208cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 'error: unable to create target for (%s) "%s"' % (self.arch, resolved_path) 209e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton else: 210e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return 'error: unable to locate main executable (%s) "%s"' % (self.arch, self.path) 21101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 212e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton def add_target_module(self): 213e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if lldb.target: 21401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.fetch_symboled_executable_and_dsym (): 215cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton resolved_path = self.get_resolved_path(); 216cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton path_spec = lldb.SBFileSpec (resolved_path) 217cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton #print 'target.AddModule (path="%s", arch="%s", uuid=%s)' % (resolved_path, self.arch, self.uuid) 218e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton self.module = lldb.target.AddModule (resolved_path, self.arch, self.uuid) 21901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.module: 22001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton err = self.load_module() 22101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if err: 22201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print err; 22301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 22401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return None 22501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 226cd793121caadf8eac0b13283bc2caa4cd467aebfGreg Clayton return 'error: unable to get module for (%s) "%s"' % (self.arch, resolved_path) 22701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 22801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return 'error: invalid target' 22901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 23001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def __init__(self, path): 23101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton """CrashLog constructor that take a path to a darwin crash log file""" 23201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.path = path; 23301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.info_lines = list() 23401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.system_profile = list() 23501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.threads = list() 23601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.images = list() 23701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.idents = list() # A list of the required identifiers for doing all stack backtraces 23801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.crashed_thread_idx = -1 23901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.version = -1 24001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # With possible initial component of ~ or ~user replaced by that user's home directory. 24101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton f = open(os.path.expanduser(self.path)) 24201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.file_lines = f.read().splitlines() 24301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_NORMAL 24401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread = None 24501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for line in self.file_lines: 24601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # print line 24701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line_len = len(line) 24801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if line_len == 0: 24901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if thread: 25001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if parse_mode == PARSE_MODE_THREAD: 25101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if thread.index == self.crashed_thread_idx: 25201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.reason = '' 25301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.thread_exception: 25401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.reason += self.thread_exception 25501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if self.thread_exception_data: 25601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.reason += " (%s)" % self.thread_exception_data 25701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.threads.append(thread) 25801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread = None 25901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 26001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # only append an extra empty line if the previous line 26101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # in the info_lines wasn't empty 26201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if len(self.info_lines) > 0 and len(self.info_lines[-1]): 26301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.info_lines.append(line) 26401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_NORMAL 26501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # print 'PARSE_MODE_NORMAL' 26601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif parse_mode == PARSE_MODE_NORMAL: 26701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if line.startswith ('Process:'): 26801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton (self.process_name, pid_with_brackets) = line[8:].strip().split() 26901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.process_id = pid_with_brackets.strip('[]') 27001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Path:'): 27101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.process_path = line[5:].strip() 27201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Identifier:'): 27301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.process_identifier = line[11:].strip() 27401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Version:'): 27501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton (self.process_version, compatability_version) = line[8:].strip().split() 27601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.process_compatability_version = compatability_version.strip('()') 27701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Parent Process:'): 27801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton (self.parent_process_name, pid_with_brackets) = line[15:].strip().split() 27901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.parent_process_id = pid_with_brackets.strip('[]') 28001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Exception Type:'): 28101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.thread_exception = line[15:].strip() 28201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 28301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Exception Codes:'): 28401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.thread_exception_data = line[16:].strip() 28501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 28601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Crashed Thread:'): 28701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.crashed_thread_idx = int(line[15:].strip().split()[0]) 28801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 28901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Report Version:'): 29001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.version = int(line[15:].strip()) 29101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 29201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('System Profile:'): 29301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_SYSTEM 29401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 29501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif (line.startswith ('Interval Since Last Report:') or 29601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line.startswith ('Crashes Since Last Report:') or 29701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line.startswith ('Per-App Interval Since Last Report:') or 29801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line.startswith ('Per-App Crashes Since Last Report:') or 29901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line.startswith ('Sleep/Wake UUID:') or 30001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line.startswith ('Anonymous UUID:')): 30101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # ignore these 30201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 30301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Thread'): 30401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_state_match = self.thread_state_regex.search (line) 30501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if thread_state_match: 30601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_state_match = self.thread_regex.search (line) 30701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_idx = int(thread_state_match.group(1)) 30801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_THREGS 30901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread = self.threads[thread_idx] 31001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 31101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_match = self.thread_regex.search (line) 31201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if thread_match: 31301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # print 'PARSE_MODE_THREAD' 31401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_THREAD 31501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread_idx = int(thread_match.group(1)) 31601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread = CrashLog.Thread(thread_idx) 31701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 31801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif line.startswith ('Binary Images:'): 31901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parse_mode = PARSE_MODE_IMAGES 32001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 32101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.info_lines.append(line.strip()) 32201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif parse_mode == PARSE_MODE_THREAD: 32301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton frame_match = self.frame_regex.search(line) 32401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if frame_match: 32501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton ident = frame_match.group(2) 32601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if not ident in self.idents: 32701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.idents.append(ident) 32801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.frames.append (CrashLog.Frame(int(frame_match.group(1)), int(frame_match.group(3), 0), frame_match.group(4))) 32901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 3308077a5334dc4daef3a145d07307a970d00563055Greg Clayton print 'error: frame regex failed for line: "%s"' % line 33101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif parse_mode == PARSE_MODE_IMAGES: 33201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match = self.image_regex_uuid.search (line) 33301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if image_match: 33401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image = CrashLog.Image (int(image_match.group(1),0), 33501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton int(image_match.group(2),0), 33601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(3).strip(), 33701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(4).strip(), 33801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(5), 33901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(6)) 34001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.images.append (image) 34101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 34201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match = self.image_regex_no_uuid.search (line) 34301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if image_match: 34401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image = CrashLog.Image (int(image_match.group(1),0), 34501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton int(image_match.group(2),0), 34601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(3).strip(), 34701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(4).strip(), 34801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton None, 34901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_match.group(5)) 35001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.images.append (image) 35101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 35201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "error: image regex failed for: %s" % line 35301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 35401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif parse_mode == PARSE_MODE_THREGS: 35501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton stripped_line = line.strip() 35601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton reg_values = stripped_line.split(' ') 35701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for reg_value in reg_values: 35801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton (reg, value) = reg_value.split(': ') 35901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.registers[reg.strip()] = int(value, 0) 36001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif parse_mode == PARSE_MODE_SYSTEM: 36101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton self.system_profile.append(line) 36201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton f.close() 36301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 36401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def dump(self): 36501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "Crash Log File: %s" % (self.path) 36601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "\nThreads:" 36701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for thread in self.threads: 36801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.dump(' ') 36901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "\nImages:" 37001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for image in self.images: 37101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image.dump(' ') 37201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 37301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton def find_image_with_identifier(self, ident): 37401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for image in self.images: 37501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if image.ident == ident: 37601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return image 37701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton return None 37801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 379e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton def create_target(self): 380e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if not self.images: 381e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return 'error: no images in crash log' 382e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton exe_path = self.images[0].get_resolved_path() 383e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton err = self.images[0].create_target () 384e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if not err: 385e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return None # success 386e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton # We weren't able to open the main executable as, but we can still symbolicate 387e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if self.idents: 388e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton for ident in idents: 389e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton image = self.find_image_with_identifier (ident) 390e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if image: 391e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton err = image.create_target () 392e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if not err: 393e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return None # success 394e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton for image in self.images: 395e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton err = image.create_target () 396e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if not err: 397e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return None # success 398e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton return 'error: unable to locate any executables from the crash log' 399e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton 400e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Claytondef disassemble_instructions (instructions, pc, insts_before_pc, insts_after_pc): 40101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton lines = list() 40201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton pc_index = -1 40301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton comment_column = 50 40401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for inst_idx, inst in enumerate(instructions): 405e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton inst_pc = inst.GetAddress().GetLoadAddress(lldb.target); 40601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if pc == inst_pc: 40701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton pc_index = inst_idx 408e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton mnemonic = inst.GetMnemonic (lldb.target) 409e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton operands = inst.GetOperands (lldb.target) 410e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton comment = inst.GetComment (lldb.target) 411e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton #data = inst.GetData (lldb.target) 41201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton lines.append ("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands)) 41301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if comment: 41401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line_len = len(lines[-1]) 41501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if line_len < comment_column: 41601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton lines[-1] += ' ' * (comment_column - line_len) 41701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton lines[-1] += "; %s" % comment 41801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 41901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if pc_index >= 0: 42001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if pc_index >= insts_before_pc: 42101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton start_idx = pc_index - insts_before_pc 42201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 42301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton start_idx = 0 42401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton end_idx = pc_index + insts_after_pc 42501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if end_idx > inst_idx: 42601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton end_idx = inst_idx 42701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for i in range(start_idx, end_idx+1): 42801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if i == pc_index: 42901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print ' -> ', lines[i] 43001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 43101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print ' ', lines[i] 43201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 43301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef print_module_section_data (section): 43401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print section 43501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton section_data = section.GetSectionData() 43601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if section_data: 43701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton ostream = lldb.SBStream() 43801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton section_data.GetDescription (ostream, section.GetFileAddress()) 43901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print ostream.GetData() 44001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 44101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef print_module_section (section, depth): 44201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print section 44301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 44401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if depth > 0: 44501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton num_sub_sections = section.GetNumSubSections() 44601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for sect_idx in range(num_sub_sections): 44701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print_module_section (section.GetSubSectionAtIndex(sect_idx), depth - 1) 44801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 44901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef print_module_sections (module, depth): 45001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for sect in module.section_iter(): 45101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print_module_section (sect, depth) 45201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 45301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef print_module_symbols (module): 45401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for sym in module: 45501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print sym 45601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 45701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef usage(): 45801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "Usage: lldb-symbolicate.py [-n name] executable-image" 45901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton sys.exit(0) 46001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 46101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef Symbolicate(debugger, command, result, dict): 46201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton SymbolicateCrashLog (command.split()) 46301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 46401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytondef SymbolicateCrashLog(command_args): 465e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton print 'command_args = %s' % command_args 466e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton parser = optparse.OptionParser(description='Parses darwin crash log files and symbolicates them.') 46701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parser.add_option('--platform', type='string', metavar='platform', dest='platform', help='specify one platform by name') 46801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parser.add_option('--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False) 46901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parser.add_option('--no-images', action='store_false', dest='show_images', help='don\'t show images in stack frames', default=True) 47001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parser.add_option('--image-list', action='store_true', dest='dump_image_list', help='show image list', default=False) 47101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parser.add_option('--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0) 472e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton parser.add_option('--crashed-only', action='store_true', dest='crashed_only', help='only symbolicate the crashed thread', default=False) 47301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton loaded_addresses = False 47401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton (options, args) = parser.parse_args(command_args) 47501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.verbose: 47601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 'options', options 47701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.debug_delay > 0: 47801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "Waiting %u seconds for debugger to attach..." % options.debug_delay 47901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton time.sleep(options.debug_delay) 48001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton error = lldb.SBError() 481e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton if args: 482e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton for crash_log_file in args: 48301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton crash_log = CrashLog(crash_log_file) 4848077a5334dc4daef3a145d07307a970d00563055Greg Clayton if options.verbose: 4858077a5334dc4daef3a145d07307a970d00563055Greg Clayton crash_log.dump() 48601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if crash_log.images: 487e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton err = crash_log.create_target () 48801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if err: 48901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print err 49001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 491e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton exe_module = lldb.target.GetModuleAtIndex(0) 49201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_paths = list() 49301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # for i in range (1, len(crash_log.images)): 49401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # image = crash_log.images[i] 49501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for ident in crash_log.idents: 49601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image = crash_log.find_image_with_identifier (ident) 49701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if image: 49801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if image.path in image_paths: 49901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo) 50001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 501e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton err = image.add_target_module () 50201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if err: 50301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print err 50401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 50501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton image_paths.append(image.path) 50601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 50701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 'error: can\'t find image for identifier "%s"' % ident 50801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 50901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for line in crash_log.info_lines: 51001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print line 51101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 51201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Reconstruct inlined frames for all threads for anything that has debug info 51301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for thread in crash_log.threads: 51401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.crashed_only and thread.did_crash() == False: 51501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 51601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # start a new frame list that we will fixup for each thread 51701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_thread_frames = list() 51801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Iterate through all concrete frames for a thread and resolve 51901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # any parent frames of inlined functions 52001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for frame_idx, frame in enumerate(thread.frames): 52101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Resolve the frame's pc into a section + offset address 'pc_addr' 522e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton pc_addr = lldb.target.ResolveLoadAddress (frame.pc) 52301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Check to see if we were able to resolve the address 52401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if pc_addr: 52501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # We were able to resolve the frame's PC into a section offset 52601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # address. 52701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 52801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Resolve the frame's PC value into a symbol context. A symbol 52901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # context can resolve a module, compile unit, function, block, 53001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # line table entry and/or symbol. If the frame has a block, then 53101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # we can look for inlined frames, which are represented by blocks 53201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # that have inlined information in them 533e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton frame.sym_ctx = lldb.target.ResolveSymbolContextForAddress (pc_addr, lldb.eSymbolContextEverything); 53401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 53501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # dump if the verbose option was specified 53601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.verbose: 53701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "frame.pc = %#16.16x (file_addr = %#16.16x)" % (frame.pc, pc_addr.GetFileAddress()) 53801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "frame.pc_addr = ", pc_addr 53901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "frame.sym_ctx = " 54001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print frame.sym_ctx 54101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 54201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 54301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Append the frame we already had from the crash log to the new 54401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # frames list 54501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_thread_frames.append(frame) 54601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 54701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_frame = CrashLog.Frame (frame.index, -1, None) 54801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 54901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Try and use the current frame's symbol context to calculate a 55001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # parent frame for an inlined function. If the curent frame is 55101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # inlined, it will return a valid symbol context for the parent 55201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # frame of the current inlined function 55301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton parent_pc_addr = lldb.SBAddress() 55401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_frame.sym_ctx = frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr) 55501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 55601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # See if we were able to reconstruct anything? 55701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton while new_frame.sym_ctx: 55801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # We have a parent frame of an inlined frame, create a new frame 55901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Convert the section + offset 'parent_pc_addr' to a load address 560e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton new_frame.pc = parent_pc_addr.GetLoadAddress(lldb.target) 56101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # push the new frame onto the new frame stack 56201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_thread_frames.append (new_frame) 56301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # dump if the verbose option was specified 56401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.verbose: 56501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "new_frame.pc = %#16.16x (%s)" % (new_frame.pc, parent_pc_addr) 56601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "new_frame.sym_ctx = " 56701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print new_frame.sym_ctx 56801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 56901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Create another new frame in case we have multiple inlined frames 57001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton prev_new_frame = new_frame 57101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_frame = CrashLog.Frame (frame.index, -1, None) 57201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Swap the addresses so we can try another inlined lookup 57301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton pc_addr = parent_pc_addr; 57401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton new_frame.sym_ctx = prev_new_frame.sym_ctx.GetParentOfInlinedScope (pc_addr, parent_pc_addr) 57501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Replace our thread frames with our new list that includes parent 57601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # frames for inlined functions 57701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton thread.frames = new_thread_frames 57801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Now iterate through all threads and display our richer stack backtraces 57901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for thread in crash_log.threads: 58001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton this_thread_crashed = thread.did_crash() 58101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.crashed_only and this_thread_crashed == False: 58201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton continue 58301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "%s" % thread 58401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton prev_frame_index = -1 58501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for frame_idx, frame in enumerate(thread.frames): 58601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details = ' %s' % frame.details 58701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton module = frame.sym_ctx.GetModule() 58801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton instructions = None 58901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if module: 59001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton module_basename = module.GetFileSpec().GetFilename(); 59101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_start_load_addr = -1 59201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_name = None 59301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function = frame.sym_ctx.GetFunction() 59401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton block = frame.sym_ctx.GetBlock() 59501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton line_entry = frame.sym_ctx.GetLineEntry() 59601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton symbol = frame.sym_ctx.GetSymbol() 59701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton inlined_block = block.GetContainingInlinedBlock(); 59801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if inlined_block: 59901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_name = inlined_block.GetInlinedName(); 600e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton block_range_idx = inlined_block.GetRangeIndexForBlockAddress (lldb.target.ResolveLoadAddress (frame.pc)) 60101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if block_range_idx < lldb.UINT32_MAX: 60201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton block_range_start_addr = inlined_block.GetRangeStartAddress (block_range_idx) 603e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton function_start_load_addr = block_range_start_addr.GetLoadAddress (lldb.target) 60401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 60501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_start_load_addr = frame.pc 60601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if this_thread_crashed and frame_idx == 0: 607e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton instructions = function.GetInstructions(lldb.target) 60801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif function: 60901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_name = function.GetName() 610e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton function_start_load_addr = function.GetStartAddress().GetLoadAddress (lldb.target) 61101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if this_thread_crashed and frame_idx == 0: 612e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton instructions = function.GetInstructions(lldb.target) 61301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif symbol: 61401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_name = symbol.GetName() 615e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton function_start_load_addr = symbol.GetStartAddress().GetLoadAddress (lldb.target) 61601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if this_thread_crashed and frame_idx == 0: 617e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton instructions = symbol.GetInstructions(lldb.target) 61801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 61901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if function_name: 62001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Print the function or symbol name and annotate if it was inlined 62101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton inline_suffix = '' 62201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if inlined_block: 62301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton inline_suffix = '[inlined] ' 62401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 62501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton inline_suffix = ' ' 62601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.show_images: 62701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details = "%s%s`%s" % (inline_suffix, module_basename, function_name) 62801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton else: 62901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details = "%s" % (function_name) 63001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Dump the offset from the current function or symbol if it is non zero 63101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton function_offset = frame.pc - function_start_load_addr 63201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if function_offset > 0: 63301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details += " + %u" % (function_offset) 63401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton elif function_offset < 0: 63501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton defaults += " %i (invalid negative offset, file a bug) " % function_offset 63601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Print out any line information if any is available 63701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if line_entry.GetFileSpec(): 63801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details += ' at %s' % line_entry.GetFileSpec().GetFilename() 63901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details += ':%u' % line_entry.GetLine () 64001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton column = line_entry.GetColumn() 64101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if column > 0: 64201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton details += ':%u' % column 64301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 64401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 64501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # Only print out the concrete frame index if it changes. 64601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # if prev_frame_index != frame.index: 64701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details) 64801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # else: 64901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton # print " %#16.16x %s" % (frame.pc, details) 65001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details) 65101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton prev_frame_index = frame.index 65201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if instructions: 65301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 654e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton disassemble_instructions (instructions, frame.pc, 4, 4) 65501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 65601f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 65701f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print 65801f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 65901f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton if options.dump_image_list: 66001f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print "Binary Images:" 66101f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton for image in crash_log.images: 66201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton print image 66301f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 66401f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 66501f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Claytonif __name__ == '__main__': 666e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton # Create a new debugger instance 667e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton lldb.debugger = lldb.SBDebugger.Create() 668e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton SymbolicateCrashLog (sys.argv) 669e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Claytonelif lldb.debugger: 670e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton lldb.debugger.HandleCommand('command script add -f crashlog.Symbolicate crashlog') 671e9ee550693aee8122d3d48b633fcff64e6a2f641Greg Clayton print '"crashlog" command installed, type "crashlog --help" for detailed help' 67201f7c96144d4604d1d120fb27643f9a29d6d1ba7Greg Clayton 673