[Lldb-commits] [lldb] r140544 - /lldb/trunk/examples/python/symbolicate-crash.py

Greg Clayton gclayton at apple.com
Mon Sep 26 11:39:23 PDT 2011


Author: gclayton
Date: Mon Sep 26 13:39:23 2011
New Revision: 140544

URL: http://llvm.org/viewvc/llvm-project?rev=140544&view=rev
Log:
Added an example that symbolicates symbol information. This file
is mostly geared towards darwin crash logs at the moment, though
it could be made more generic with a few tweaks. 

The symbolicate-crash.py script will make a target given a crash log
and then symbolicate all frames and expand any frames that had inlined
functions in them to show all frames back to the concrete function. It
will also disassemble around the crash site.


Added:
    lldb/trunk/examples/python/symbolicate-crash.py   (with props)

Added: lldb/trunk/examples/python/symbolicate-crash.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/symbolicate-crash.py?rev=140544&view=auto
==============================================================================
--- lldb/trunk/examples/python/symbolicate-crash.py (added)
+++ lldb/trunk/examples/python/symbolicate-crash.py Mon Sep 26 13:39:23 2011
@@ -0,0 +1,565 @@
+#!/usr/bin/python
+
+#----------------------------------------------------------------------
+# Be sure to add the python path that points to the LLDB shared library.
+# On MacOSX csh, tcsh:
+#   setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
+# On MacOSX sh, bash:
+#   export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
+#----------------------------------------------------------------------
+
+import lldb
+import optparse
+import os
+import re
+import sys
+import time
+
+PARSE_MODE_NORMAL = 0
+PARSE_MODE_THREAD = 1
+PARSE_MODE_IMAGES = 2
+PARSE_MODE_THREGS = 3
+PARSE_MODE_SYSTEM = 4
+
+class CrashLog:
+    """Class that does parses darwin crash logs"""
+    thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
+    thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)')
+    frame_regex = re.compile('^([0-9]+).*(0x[0-9a-fA-F]+) +(.*)')
+    image_regex = re.compile('(0x[0-9a-fA-F]+)[- ]+(0x[0-9a-fA-F]+) +([^ ]+) +([\.0-9\?]+) \(([^)]+)\) <([-0-9a-fA-F]+)> (.*)');
+    empty_line_regex = re.compile('^$')
+    
+    class Thread:
+        """Class that represents a thread in a darwin crash log"""
+        def __init__(self, index):
+            self.index = index
+            self.frames = list()
+            self.registers = dict()
+            self.reason = None
+            self.queue = None
+        
+        def dump(self, prefix):
+            print "%sThread[%u] %s" % (prefix, self.index, self.reason)
+            if self.frames:
+                print "%s  Frames:" % (prefix)
+                for frame in self.frames:
+                    frame.dump(prefix + '    ')
+            if self.registers:
+                print "%s  Registers:" % (prefix)
+                for reg in self.registers.keys():
+                    print "%s    %-5s = %#16.16x" % (prefix, reg, self.registers[reg])
+        
+        def did_crash(self):
+            return self.reason != None
+        
+        def __str__(self):
+            s = "Thread[%u]" % self.index
+            if self.reason:
+                s += ' %s' % self.reason
+            return s
+
+    class Frame:
+        """Class that represents a stack frame in a thread in a darwin crash log"""
+        def __init__(self, index, pc, details):
+            self.index = index
+            self.pc = pc
+            self.sym_ctx = None
+            self.details = details
+
+        def __str__(self):
+            return "[%2u] %#16.16x %s" % (self.index, self.pc, self.details)
+            
+        def dump(self, prefix):
+            print "%s%s" % (prefix, self)
+    
+    class Image:
+        """Class that represents a binary images in a darwin crash log"""
+        def __init__(self, text_addr_lo, text_addr_hi, ident, version, compatability_version, uuid, path):
+            self.text_addr_lo = text_addr_lo
+            self.text_addr_hi = text_addr_hi
+            self.ident = ident
+            self.version = version
+            self.compatability_version = compatability_version
+            self.uuid = uuid
+            self.path = path
+ 
+        def dump(self, prefix):
+            print "%s%s" % (prefix, self)
+
+        def __str__(self):
+            return "%#16.16x %s %s" % (self.text_addr_lo, self.uuid, self.path)
+    
+    
+    def __init__(self, path):
+        """CrashLog constructor that take a path to a darwin crash log file"""
+        self.path = path;
+        self.info_lines = list()
+        self.system_profile = list()
+        self.threads = list()
+        self.images = list()
+        self.crashed_thread_idx = -1
+        self.version = -1
+        f = open(self.path)
+        self.file_lines = f.read().splitlines()
+        parse_mode = PARSE_MODE_NORMAL
+        thread = None
+        for line in self.file_lines:
+            # print line
+            line_len = len(line)
+            if line_len == 0:
+                if thread:
+                    if parse_mode == PARSE_MODE_THREAD:
+                        if thread.index == self.crashed_thread_idx:
+                            thread.reason = ''
+                            if self.thread_exception:
+                                thread.reason += self.thread_exception
+                            if self.thread_exception_data:
+                                thread.reason += " (%s)" % self.thread_exception_data                                
+                        self.threads.append(thread)
+                    thread = None
+                else:
+                    # only append an extra empty line if the previous line 
+                    # in the info_lines wasn't empty
+                    if len(self.info_lines) > 0 and len(self.info_lines[-1]):
+                        self.info_lines.append(line)
+                parse_mode = PARSE_MODE_NORMAL
+                # print 'PARSE_MODE_NORMAL'
+            elif parse_mode == PARSE_MODE_NORMAL:
+                if line.startswith ('Process:'):
+                    (self.process_name, pid_with_brackets) = line[8:].strip().split()
+                    self.process_id = pid_with_brackets.strip('[]')
+                elif line.startswith ('Path:'):
+                    self.process_path = line[5:].strip()
+                elif line.startswith ('Identifier:'):
+                    self.process_identifier = line[11:].strip()
+                elif line.startswith ('Version:'):
+                    (self.process_version, compatability_version) = line[8:].strip().split()
+                    self.process_compatability_version = compatability_version.strip('()')
+                elif line.startswith ('Parent Process:'):
+                    (self.parent_process_name, pid_with_brackets) = line[15:].strip().split()
+                    self.parent_process_id = pid_with_brackets.strip('[]') 
+                elif line.startswith ('Exception Type:'):
+                    self.thread_exception = line[15:].strip()
+                    continue
+                elif line.startswith ('Exception Codes:'):
+                    self.thread_exception_data = line[16:].strip()
+                    continue
+                elif line.startswith ('Crashed Thread:'):
+                    self.crashed_thread_idx = int(line[15:].strip().split()[0])
+                    continue
+                elif line.startswith ('Report Version:'):
+                    self.version = int(line[15:].strip())
+                    continue
+                elif line.startswith ('System Profile:'):
+                    parse_mode = PARSE_MODE_SYSTEM
+                    continue
+                elif (line.startswith ('Interval Since Last Report:') or
+                      line.startswith ('Crashes Since Last Report:') or
+                      line.startswith ('Per-App Interval Since Last Report:') or
+                      line.startswith ('Per-App Crashes Since Last Report:') or
+                      line.startswith ('Sleep/Wake UUID:') or
+                      line.startswith ('Anonymous UUID:')):
+                    # ignore these
+                    continue  
+                elif line.startswith ('Thread'):
+                    thread_state_match = self.thread_state_regex.search (line)
+                    if thread_state_match:
+                        thread_state_match = self.thread_regex.search (line)
+                        thread_idx = int(thread_state_match.group(1))
+                        parse_mode = PARSE_MODE_THREGS
+                        thread = self.threads[thread_idx]
+                    else:
+                        thread_match = self.thread_regex.search (line)
+                        if thread_match:
+                            # print 'PARSE_MODE_THREAD'
+                            parse_mode = PARSE_MODE_THREAD
+                            thread_idx = int(thread_match.group(1))
+                            thread = CrashLog.Thread(thread_idx)
+                    continue
+                elif line.startswith ('Binary Images:'):
+                    parse_mode = PARSE_MODE_IMAGES
+                    continue
+                self.info_lines.append(line.strip())
+            elif parse_mode == PARSE_MODE_THREAD:
+                frame_match = self.frame_regex.search(line)
+                if frame_match:
+                    thread.frames.append (CrashLog.Frame(int(frame_match.group(1)), int(frame_match.group(2), 0), frame_match.group(3)))
+                else:
+                    print "error: frame regex failed"
+            elif parse_mode == PARSE_MODE_IMAGES:
+                image_match = self.image_regex.search (line)
+                if image_match:
+                    image = CrashLog.Image (int(image_match.group(1),0), 
+                                            int(image_match.group(2),0), 
+                                            image_match.group(3), 
+                                            image_match.group(4), 
+                                            image_match.group(5), 
+                                            image_match.group(6), 
+                                            image_match.group(7))
+                    self.images.append (image)
+                else:
+                    print "error: image regex failed"
+            elif parse_mode == PARSE_MODE_THREGS:
+                stripped_line = line.strip()
+                reg_values = stripped_line.split('  ')
+                for reg_value in reg_values:
+                    (reg, value) = reg_value.split(': ')
+                    thread.registers[reg.strip()] = int(value, 0)
+            elif parse_mode == PARSE_MODE_SYSTEM:
+                self.system_profile.append(line)
+        f.close()
+        
+    def dump(self):
+        print "Crash Log File: %s" % (self.path)
+        print "\nThreads:"
+        for thread in self.threads:
+            thread.dump('  ')
+        print "\nImages:"
+        for image in self.images:
+            image.dump('  ')
+
+def disassemble_instructions (target, instructions, pc, insts_before_pc, insts_after_pc):
+    lines = list()
+    pc_index = -1
+    comment_column = 50
+    for inst_idx, inst in enumerate(instructions):
+        inst_pc = inst.GetAddress().GetLoadAddress(target);
+        if pc == inst_pc:
+            pc_index = inst_idx
+        opcode_name = inst.GetOpcodeName(target)
+        mnemonics =  inst.GetMnemonics(target)
+        comment =  inst.GetComment(target)
+        #data = inst.GetData(target)
+        lines.append ("%#16.16x: %8s %s" % (inst_pc, opcode_name, mnemonics))
+        if comment:
+            line_len = len(lines[-1])
+            if line_len < comment_column:
+                lines[-1] += ' ' * (comment_column - line_len)
+                lines[-1] += "; %s" % comment
+
+    if pc_index >= 0:
+        if pc_index >= insts_before_pc:
+            start_idx = pc_index - insts_before_pc
+        else:
+            start_idx = 0
+        end_idx = pc_index + insts_after_pc
+        if end_idx > inst_idx:
+            end_idx = inst_idx
+        for i in range(start_idx, end_idx+1):
+            if i == pc_index:
+                print ' -> ', lines[i]
+            else:
+                print '    ', lines[i]
+
+def print_module_section_data (section):
+    print section
+    section_data = section.GetSectionData()
+    if section_data:
+        ostream = lldb.SBStream()
+        section_data.GetDescription (ostream, section.GetFileAddress())
+        print ostream.GetData()
+
+def print_module_section (section, depth):
+    print section
+            
+    if depth > 0:
+        num_sub_sections = section.GetNumSubSections()
+        for sect_idx in range(num_sub_sections):
+            print_module_section (section.GetSubSectionAtIndex(sect_idx), depth - 1)
+
+def print_module_sections (module, depth):
+    num_sections = module.GetNumSections()
+
+    for sect_idx in range(num_sections):
+        section = module.GetSectionAtIndex(sect_idx)
+        print_module_section (section, depth)
+
+def print_module_symbols (module):
+    n = module.GetNumSymbols()
+
+    for i in range(n):
+        print module.GetSymbolAtIndex(i)
+
+def usage():
+    print "Usage: lldb-symbolicate.py [-n name] executable-image"
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser(description='A script that parses skinny and universal mach-o files.')
+    parser.add_option('--arch', type='string', metavar='arch', dest='triple', help='specify one architecture or target triple')
+    parser.add_option('--platform', type='string', metavar='platform', dest='platform', help='specify one platform by name')
+    parser.add_option('--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
+    parser.add_option('--interactive', action='store_true', dest='interactive', help='enable interactive mode', default=False)
+    parser.add_option('--no-images', action='store_false', dest='show_images', help='don\'t show images in stack frames', default=True)
+    parser.add_option('--no-dependents', action='store_false', dest='dependents', help='skip loading dependent modules', default=True)
+    parser.add_option('--sections', action='store_true', dest='dump_sections', help='show module sections', default=False)
+    parser.add_option('--symbols', action='store_true', dest='dump_symbols', help='show module symbols', default=False)
+    parser.add_option('--image-list', action='store_true', dest='dump_image_list', help='show image list', default=False)
+    parser.add_option('--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0)
+    parser.add_option('--section-depth', type='int', dest='section_depth', help='set the section depth to use when showing sections', default=0)
+    parser.add_option('--section-data', type='string', action='append', dest='sect_data_names', help='specify sections by name to display data for')
+    parser.add_option('--address', type='int', action='append', dest='addresses', help='specify addresses to lookup')
+    parser.add_option('--crash-log', type='string', action='append', dest='crash_log_files', help='specify crash log files to symbolicate')
+    parser.add_option('--crashed-only', action='store_true', dest='crashed_only', help='only show the crashed thread', default=False)
+    loaded_addresses = False
+    (options, args) = parser.parse_args()
+    if options.verbose:
+        print 'options', options
+
+    if options.debug_delay > 0:
+        print "Waiting %u seconds for debugger to attach..." % options.debug_delay
+        time.sleep(options.debug_delay)
+
+    # Create a new debugger instance
+    debugger = lldb.SBDebugger.Create()
+
+    # When we step or continue, don't return from the function until the process 
+    # stops. We do this by setting the async mode to false.
+    debugger.SetAsync (False)
+    error = lldb.SBError()
+    
+    if options.crash_log_files:
+        options.dependents = False
+        for crash_log_file in options.crash_log_files:
+            triple = "x86_64"
+            crash_log = CrashLog(crash_log_file)
+            #crash_log.dump()
+            target = debugger.CreateTarget (crash_log.process_path, options.triple, options.platform, options.dependents, error);
+            exe_module = target.GetModuleAtIndex(0)
+            loaded_images = list()
+            for image in crash_log.images:
+                if image.path == crash_log.process_path:
+                    module = exe_module
+                else:
+                    module = target.AddModule (image.path, options.triple, image.uuid)
+                if module in loaded_images:
+                    print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo)
+                else:
+                    loaded_images.append(module)
+                    if image.uuid != module.GetUUIDString():
+                        print "error: couln't find %s", image.uuid
+                    target.SetSectionLoadAddress (module.FindSection ("__TEXT"), image.text_addr_lo)
+            for line in crash_log.info_lines:
+                print line
+            print "fixing up inlined frames"
+            # Reconstruct inlined frames for all threads for anything that has debug info
+            for thread in crash_log.threads:
+                if options.crashed_only and thread.did_crash() == False:
+                    continue
+                # start a new frame list that we will fixup for each thread
+                new_thread_frames = list()
+                # Iterate through all concrete frames for a thread and resolve
+                # any parent frames of inlined functions
+                for frame_idx, frame in enumerate(thread.frames):
+                    # Resolve the frame's pc into a section + offset address 'pc_addr'
+                    pc_addr = target.ResolveLoadAddress (frame.pc)
+                    # Check to see if we were able to resolve the address
+                    if pc_addr:
+                        # We were able to resolve the frame's PC into a section offset
+                        # address.
+                        
+                        # Resolve the frame's PC value into a symbol context. A symbol
+                        # context can resolve a module, compile unit, function, block,
+                        # line table entry and/or symbol. If the frame has a block, then
+                        # we can look for inlined frames, which are represented by blocks
+                        # that have inlined information in them
+                        frame.sym_ctx = target.ResolveSymbolContextForAddress (pc_addr, lldb.eSymbolContextEverything);
+                        
+                        # dump if the verbose option was specified
+                        if options.verbose:
+                            print "frame.pc = %#16.16x (file_addr = %#16.16x)" % (frame.pc, pc_addr.GetFileAddress())
+                            print "frame.pc_addr = ", pc_addr
+                            print "frame.sym_ctx = "
+                            print frame.sym_ctx
+                            print
+                        
+                        # Append the frame we already had from the crash log to the new
+                        # frames list
+                        new_thread_frames.append(frame)
+
+                        new_frame = CrashLog.Frame (frame.index, -1, None)
+
+                        # Try and use the current frame's symbol context to calculate a 
+                        # parent frame for an inlined function. If the curent frame is
+                        # inlined, it will return a valid symbol context for the parent 
+                        # frame of the current inlined function
+                        parent_pc_addr = lldb.SBAddress()
+                        new_frame.sym_ctx = frame.sym_ctx.GetParentInlinedFrameInfo (pc_addr, True, parent_pc_addr)
+
+                        # See if we were able to reconstruct anything?
+                        while new_frame.sym_ctx:
+                            # We have a parent frame of an inlined frame, create a new frame
+                            # Convert the section + offset 'parent_pc_addr' to a load address 
+                            new_frame.pc = parent_pc_addr.GetLoadAddress(target)
+                            # push the new frame onto the new frame stack
+                            new_thread_frames.append (new_frame)
+                            # dump if the verbose option was specified
+                            if options.verbose:
+                                print "new_frame.pc = %#16.16x (%s)" % (new_frame.pc, parent_pc_addr)
+                                print "new_frame.sym_ctx = "
+                                print new_frame.sym_ctx
+                                print
+                            # Create another new frame in case we have multiple inlined frames
+                            prev_new_frame = new_frame
+                            new_frame = CrashLog.Frame (frame.index, -1, None)
+                            # Swap the addresses so we can try another inlined lookup
+                            pc_addr = parent_pc_addr;
+                            new_frame.sym_ctx = prev_new_frame.sym_ctx.GetParentInlinedFrameInfo (pc_addr, False, parent_pc_addr)
+                # Replace our thread frames with our new list that includes parent
+                # frames for inlined functions
+                thread.frames = new_thread_frames
+            # Now iterate through all threads and display our richer stack backtraces
+            for thread in crash_log.threads:
+                this_thread_crashed = thread.did_crash()
+                if options.crashed_only and this_thread_crashed == False:
+                    continue
+                print "%s" % thread
+                prev_frame_index = -1
+                for frame_idx, frame in enumerate(thread.frames):
+                    details = "[%u] %s (carp)" % (frame_idx, frame)
+                    module = frame.sym_ctx.GetModule()
+                    instructions = None
+                    if module:
+                        module_basename = module.GetFileSpec().GetFilename();
+                        function_start_load_addr = -1
+                        function_name = None
+                        function = frame.sym_ctx.GetFunction()
+                        block = frame.sym_ctx.GetBlock()
+                        line_entry = frame.sym_ctx.GetLineEntry()
+                        symbol = frame.sym_ctx.GetSymbol()
+                        inlined_block = block.GetContainingInlinedBlock();
+                        if inlined_block:
+                            function_name = inlined_block.GetInlinedName();
+                            block_range_idx = inlined_block.GetRangeIndexForBlockAddress (target.ResolveLoadAddress (frame.pc))
+                            if block_range_idx < lldb.UINT32_MAX:
+                                block_range_start_addr = inlined_block.GetRangeStartAddress (block_range_idx)
+                                function_start_load_addr = block_range_start_addr.GetLoadAddress (target)
+                            else:
+                                function_start_load_addr = frame.pc
+                            if this_thread_crashed and frame_idx == 0:
+                                instructions = function.GetInstructions(target)
+                        elif function:
+                            function_name = function.GetName()
+                            function_start_load_addr = function.GetStartAddress().GetLoadAddress (target)
+                            if this_thread_crashed and frame_idx == 0:
+                                instructions = function.GetInstructions(target)
+                        elif symbol:
+                            function_name = symbol.GetName()
+                            function_start_load_addr = symbol.GetStartAddress().GetLoadAddress (target)
+                            if this_thread_crashed and frame_idx == 0:
+                                instructions = symbol.GetInstructions(target)
+
+                        if function_name:
+                            # Print the function or symbol name and annotate if it was inlined
+                            inline_suffix = ''
+                            if inlined_block: 
+                                inline_suffix = '[inlined] '
+                            else:
+                                inline_suffix = '          '
+                            if options.show_images:
+                                details = "%s%s`%s" % (inline_suffix, module_basename, function_name)
+                            else:
+                                details = "%s" % (function_name)
+                            # Dump the offset from the current function or symbol if it is non zero
+                            function_offset = frame.pc - function_start_load_addr
+                            if function_offset > 0:
+                                details += " + %u" % (function_offset)
+                            elif function_offset < 0:
+                                defaults += " %i (invalid negative offset, file a bug) " % function_offset
+                            # Print out any line information if any is available
+                            if line_entry.GetFileSpec():
+                                details += ' at %s' % line_entry.GetFileSpec().GetFilename()
+                                details += ':%u' % line_entry.GetLine ()
+                                column = line_entry.GetColumn()
+                                if column > 0:
+                                    details += ':%u' % column
+                        else:
+                            print "error: no function name!"
+                            
+                        
+                    # Only print out the concrete frame index if it changes.
+                    # if prev_frame_index != frame.index:
+                    #     print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
+                    # else:
+                    #     print "     %#16.16x %s" % (frame.pc, details)
+                    print "[%2u] %#16.16x %s" % (frame.index, frame.pc, details)
+                    prev_frame_index = frame.index
+                    if instructions:
+                        print
+                        disassemble_instructions (target, instructions, frame.pc, 4, 4)
+                        print
+                        
+                print                
+
+            if options.dump_image_list:
+                print "Binary Images:"
+                for image in crash_log.images:
+                    print image
+    else:
+        for exe_file in args:
+
+            # Create a target from a file and arch
+            print "Creating a target for '%s'" % exe_file
+
+            target = debugger.CreateTarget (exe_file, options.triple, options.platform, options.dependents, error);
+        
+            if target:
+                exe_module = None;
+                module_count = target.GetNumModules();
+                for module_idx in range(module_count):
+                    module = target.GetModuleAtIndex (module_idx)
+                    if module_idx == 0:
+                        exe_module = module
+                    print "module[%u] = %s" % (module_idx, module)
+            
+                    if options.dump_symbols:
+                        print_module_symbols (module)
+                    if options.dump_sections:
+                        print_module_sections (module, options.section_depth)
+                    if options.sect_data_names:
+                        for sect_name in options.sect_data_names:
+                            section = module.FindSection (sect_name)
+                            if section:
+                                print_module_section_data (section)
+                            else:
+                                print "No section was found in '%s' named '%s'" % (module, sect_name)
+                if options.addresses:
+                    for address in options.addresses:
+                        if loaded_addresses:
+                            so_address = target.ResolveLoadAddress (address)
+                            if so_address:
+                                print so_address
+                                so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
+                                print so_address_sc
+                            else:
+                                print "error: 0x%8.8x failed to resolve as a load address" % (address)
+                        else:
+                            so_address = exe_module.ResolveFileAddress (address)
+                
+                            if so_address:
+                                print so_address
+                                so_address_sc = exe_module.ResolveSymbolContextForAddress (so_address, lldb.eSymbolContextEverything);
+                                print so_address_sc
+                            else:
+                                print "error: 0x%8.8x failed to resolve as a file address in %s" % (address, exe_module)
+                
+                    # text_base_addr = 0x10000
+                    # load_addr = 0x10bb0
+                    # text_segment = exe_module.FindSection ("__TEXT")
+                    # if text_segment:
+                    #     target.SetSectionLoadAddress (text_segment, text_base_addr)
+                    # 
+                    #     load_so_addr = target.ResolveLoadAddress (load_addr)
+                    # 
+                    #     if load_so_addr:
+                    #         sc = target.ResolveSymbolContextForAddress (so_addr, lldb.eSymbolContextEverything);
+                    #         print sc
+                    #     else:
+                    #         print "error: 0x%8.8x failed to resolve as a load address" % (load_addr)
+            else:
+                print "error: ", error
+
+
+    lldb.SBDebugger.Terminate()
+        

Propchange: lldb/trunk/examples/python/symbolicate-crash.py
------------------------------------------------------------------------------
    svn:executable = *





More information about the lldb-commits mailing list