Home | History | Annotate | Download | only in test
      1 """
      2 This LLDB module contains miscellaneous utilities.
      3 Some of the test suite takes advantage of the utility functions defined here.
      4 They can also be useful for general purpose lldb scripting.
      5 """
      6 
      7 import lldb
      8 import os, sys
      9 import StringIO
     10 
     11 # ===================================================
     12 # Utilities for locating/checking executable programs
     13 # ===================================================
     14 
     15 def is_exe(fpath):
     16     """Returns True if fpath is an executable."""
     17     return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
     18 
     19 def which(program):
     20     """Returns the full path to a program; None otherwise."""
     21     fpath, fname = os.path.split(program)
     22     if fpath:
     23         if is_exe(program):
     24             return program
     25     else:
     26         for path in os.environ["PATH"].split(os.pathsep):
     27             exe_file = os.path.join(path, program)
     28             if is_exe(exe_file):
     29                 return exe_file
     30     return None
     31 
     32 # ===================================================
     33 # Disassembly for an SBFunction or an SBSymbol object
     34 # ===================================================
     35 
     36 def disassemble(target, function_or_symbol):
     37     """Disassemble the function or symbol given a target.
     38 
     39     It returns the disassembly content in a string object.
     40     """
     41     buf = StringIO.StringIO()
     42     insts = function_or_symbol.GetInstructions(target)
     43     for i in insts:
     44         print >> buf, i
     45     return buf.getvalue()
     46 
     47 # ==========================================================
     48 # Integer (byte size 1, 2, 4, and 8) to bytearray conversion
     49 # ==========================================================
     50 
     51 def int_to_bytearray(val, bytesize):
     52     """Utility function to convert an integer into a bytearray.
     53 
     54     It returns the bytearray in the little endian format.  It is easy to get the
     55     big endian format, just do ba.reverse() on the returned object.
     56     """
     57     import struct
     58 
     59     if bytesize == 1:
     60         return bytearray([val])
     61 
     62     # Little endian followed by a format character.
     63     template = "<%c"
     64     if bytesize == 2:
     65         fmt = template % 'h'
     66     elif bytesize == 4:
     67         fmt = template % 'i'
     68     elif bytesize == 4:
     69         fmt = template % 'q'
     70     else:
     71         return None
     72 
     73     packed = struct.pack(fmt, val)
     74     return bytearray(map(ord, packed))
     75 
     76 def bytearray_to_int(bytes, bytesize):
     77     """Utility function to convert a bytearray into an integer.
     78 
     79     It interprets the bytearray in the little endian format. For a big endian
     80     bytearray, just do ba.reverse() on the object before passing it in.
     81     """
     82     import struct
     83 
     84     if bytesize == 1:
     85         return bytes[0]
     86 
     87     # Little endian followed by a format character.
     88     template = "<%c"
     89     if bytesize == 2:
     90         fmt = template % 'h'
     91     elif bytesize == 4:
     92         fmt = template % 'i'
     93     elif bytesize == 4:
     94         fmt = template % 'q'
     95     else:
     96         return None
     97 
     98     unpacked = struct.unpack(fmt, str(bytes))
     99     return unpacked[0]
    100 
    101 
    102 # ==============================================================
    103 # Get the description of an lldb object or None if not available
    104 # ==============================================================
    105 def get_description(obj, option=None):
    106     """Calls lldb_obj.GetDescription() and returns a string, or None.
    107 
    108     For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
    109     option can be passed in to describe the detailed level of description
    110     desired:
    111         o lldb.eDescriptionLevelBrief
    112         o lldb.eDescriptionLevelFull
    113         o lldb.eDescriptionLevelVerbose
    114     """
    115     method = getattr(obj, 'GetDescription')
    116     if not method:
    117         return None
    118     tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
    119     if isinstance(obj, tuple):
    120         if option is None:
    121             option = lldb.eDescriptionLevelBrief
    122 
    123     stream = lldb.SBStream()
    124     if option is None:
    125         success = method(stream)
    126     else:
    127         success = method(stream, option)
    128     if not success:
    129         return None
    130     return stream.GetData()
    131         
    132 
    133 # =================================================
    134 # Convert some enum value to its string counterpart
    135 # =================================================
    136 
    137 def state_type_to_str(enum):
    138     """Returns the stateType string given an enum."""
    139     if enum == lldb.eStateInvalid:
    140         return "invalid"
    141     elif enum == lldb.eStateUnloaded:
    142         return "unloaded"
    143     elif enum == lldb.eStateConnected:
    144         return "connected"
    145     elif enum == lldb.eStateAttaching:
    146         return "attaching"
    147     elif enum == lldb.eStateLaunching:
    148         return "launching"
    149     elif enum == lldb.eStateStopped:
    150         return "stopped"
    151     elif enum == lldb.eStateRunning:
    152         return "running"
    153     elif enum == lldb.eStateStepping:
    154         return "stepping"
    155     elif enum == lldb.eStateCrashed:
    156         return "crashed"
    157     elif enum == lldb.eStateDetached:
    158         return "detached"
    159     elif enum == lldb.eStateExited:
    160         return "exited"
    161     elif enum == lldb.eStateSuspended:
    162         return "suspended"
    163     else:
    164         raise Exception("Unknown StateType enum")
    165 
    166 def stop_reason_to_str(enum):
    167     """Returns the stopReason string given an enum."""
    168     if enum == lldb.eStopReasonInvalid:
    169         return "invalid"
    170     elif enum == lldb.eStopReasonNone:
    171         return "none"
    172     elif enum == lldb.eStopReasonTrace:
    173         return "trace"
    174     elif enum == lldb.eStopReasonBreakpoint:
    175         return "breakpoint"
    176     elif enum == lldb.eStopReasonWatchpoint:
    177         return "watchpoint"
    178     elif enum == lldb.eStopReasonSignal:
    179         return "signal"
    180     elif enum == lldb.eStopReasonException:
    181         return "exception"
    182     elif enum == lldb.eStopReasonPlanComplete:
    183         return "plancomplete"
    184     elif enum == lldb.eStopReasonThreadExiting:
    185         return "threadexiting"
    186     else:
    187         raise Exception("Unknown StopReason enum")
    188 
    189 def symbol_type_to_str(enum):
    190     """Returns the symbolType string given an enum."""
    191     if enum == lldb.eSymbolTypeInvalid:
    192         return "invalid"
    193     elif enum == lldb.eSymbolTypeAbsolute:
    194         return "absolute"
    195     elif enum == lldb.eSymbolTypeCode:
    196         return "code"
    197     elif enum == lldb.eSymbolTypeData:
    198         return "data"
    199     elif enum == lldb.eSymbolTypeTrampoline:
    200         return "trampoline"
    201     elif enum == lldb.eSymbolTypeRuntime:
    202         return "runtime"
    203     elif enum == lldb.eSymbolTypeException:
    204         return "exception"
    205     elif enum == lldb.eSymbolTypeSourceFile:
    206         return "sourcefile"
    207     elif enum == lldb.eSymbolTypeHeaderFile:
    208         return "headerfile"
    209     elif enum == lldb.eSymbolTypeObjectFile:
    210         return "objectfile"
    211     elif enum == lldb.eSymbolTypeCommonBlock:
    212         return "commonblock"
    213     elif enum == lldb.eSymbolTypeBlock:
    214         return "block"
    215     elif enum == lldb.eSymbolTypeLocal:
    216         return "local"
    217     elif enum == lldb.eSymbolTypeParam:
    218         return "param"
    219     elif enum == lldb.eSymbolTypeVariable:
    220         return "variable"
    221     elif enum == lldb.eSymbolTypeVariableType:
    222         return "variabletype"
    223     elif enum == lldb.eSymbolTypeLineEntry:
    224         return "lineentry"
    225     elif enum == lldb.eSymbolTypeLineHeader:
    226         return "lineheader"
    227     elif enum == lldb.eSymbolTypeScopeBegin:
    228         return "scopebegin"
    229     elif enum == lldb.eSymbolTypeScopeEnd:
    230         return "scopeend"
    231     elif enum == lldb.eSymbolTypeAdditional:
    232         return "additional"
    233     elif enum == lldb.eSymbolTypeCompiler:
    234         return "compiler"
    235     elif enum == lldb.eSymbolTypeInstrumentation:
    236         return "instrumentation"
    237     elif enum == lldb.eSymbolTypeUndefined:
    238         return "undefined"
    239 
    240 def value_type_to_str(enum):
    241     """Returns the valueType string given an enum."""
    242     if enum == lldb.eValueTypeInvalid:
    243         return "invalid"
    244     elif enum == lldb.eValueTypeVariableGlobal:
    245         return "global_variable"
    246     elif enum == lldb.eValueTypeVariableStatic:
    247         return "static_variable"
    248     elif enum == lldb.eValueTypeVariableArgument:
    249         return "argument_variable"
    250     elif enum == lldb.eValueTypeVariableLocal:
    251         return "local_variable"
    252     elif enum == lldb.eValueTypeRegister:
    253         return "register"
    254     elif enum == lldb.eValueTypeRegisterSet:
    255         return "register_set"
    256     elif enum == lldb.eValueTypeConstResult:
    257         return "constant_result"
    258     else:
    259         raise Exception("Unknown ValueType enum")
    260 
    261 
    262 # ==================================================
    263 # Get stopped threads due to each stop reason.
    264 # ==================================================
    265 
    266 def sort_stopped_threads(process,
    267                          breakpoint_threads = None,
    268                          crashed_threads = None,
    269                          watchpoint_threads = None,
    270                          signal_threads = None,
    271                          exiting_threads = None,
    272                          other_threads = None):
    273     """ Fills array *_threads with threads stopped for the corresponding stop
    274         reason.
    275     """
    276     for lst in [breakpoint_threads,
    277                 watchpoint_threads,
    278                 signal_threads,
    279                 exiting_threads,
    280                 other_threads]:
    281         if lst is not None:
    282             lst[:] = []
    283 
    284     for thread in process:
    285         dispatched = False
    286         for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
    287                                (lldb.eStopReasonException, crashed_threads),
    288                                (lldb.eStopReasonWatchpoint, watchpoint_threads),
    289                                (lldb.eStopReasonSignal, signal_threads),
    290                                (lldb.eStopReasonThreadExiting, exiting_threads),
    291                                (None, other_threads)]:
    292             if not dispatched and list is not None:
    293                 if thread.GetStopReason() == reason or reason is None:
    294                     list.append(thread)
    295                     dispatched = True
    296 
    297 # ==================================================
    298 # Utility functions for setting breakpoints
    299 # ==================================================
    300 
    301 def run_break_set_by_file_and_line (test, file_name, line_number, extra_options = None, num_expected_locations = 1, loc_exact=False, module_name=None):
    302     """Set a breakpoint by file and line, returning the breakpoint number. 
    303 
    304     If extra_options is not None, then we append it to the breakpoint set command.
    305 
    306     If num_expected_locations is -1 we check that we got AT LEAST one location, otherwise we check that num_expected_locations equals the number of locations.
    307 
    308     If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
    309 
    310     if file_name == None:
    311         command = 'breakpoint set -l %d'%(line_number)
    312     else:
    313         command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
    314 
    315     if module_name:
    316         command += " --shlib '%s'" % (module_name)
    317 
    318     if extra_options:
    319         command += " " + extra_options
    320 
    321     break_results = run_break_set_command (test, command)
    322 
    323     if num_expected_locations == 1 and loc_exact:
    324         check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name)
    325     else:
    326         check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
    327 
    328     return get_bpno_from_match (break_results)
    329 
    330 def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None):
    331     """Set a breakpoint by symbol name.  Common options are the same as run_break_set_by_file_and_line.
    332 
    333     If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
    334     command = 'breakpoint set -n "%s"'%(symbol)
    335 
    336     if module_name:
    337         command += " --shlib '%s'" % (module_name)
    338 
    339     if extra_options:
    340         command += " " + extra_options
    341 
    342     break_results = run_break_set_command (test, command)
    343 
    344     if num_expected_locations == 1 and sym_exact:
    345         check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name)
    346     else:
    347         check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
    348 
    349     return get_bpno_from_match (break_results)
    350 
    351 def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
    352     """Set a breakpoint by selector.  Common options are the same as run_break_set_by_file_and_line."""
    353 
    354     command = 'breakpoint set -S "%s"' % (selector)
    355 
    356     if module_name:
    357         command += ' --shlib "%s"' % (module_name)
    358 
    359     if extra_options:
    360         command += " " + extra_options
    361 
    362     break_results = run_break_set_command (test, command)
    363 
    364     if num_expected_locations == 1:
    365         check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name)
    366     else:
    367         check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
    368 
    369     return get_bpno_from_match (break_results)
    370 
    371 def run_break_set_by_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
    372     """Set a breakpoint by regular expression match on symbol name.  Common options are the same as run_break_set_by_file_and_line."""
    373 
    374     command = 'breakpoint set -r "%s"'%(regexp)
    375     if extra_options:
    376         command += " " + extra_options
    377     
    378     break_results = run_break_set_command (test, command)
    379     
    380     check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
    381 
    382     return get_bpno_from_match (break_results)
    383 
    384 def run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
    385     """Set a breakpoint by source regular expression.  Common options are the same as run_break_set_by_file_and_line."""
    386     command = 'breakpoint set -p "%s"'%(regexp)
    387     if extra_options:
    388         command += " " + extra_options
    389     
    390     break_results = run_break_set_command (test, command)
    391     
    392     check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
    393 
    394     return get_bpno_from_match (break_results)
    395 
    396 def run_break_set_command (test, command):
    397     """Run the command passed in - it must be some break set variant - and analyze the result.  
    398     Returns a dictionary of information gleaned from the command-line results.
    399     Will assert if the breakpoint setting fails altogether.
    400 
    401     Dictionary will contain:
    402         bpno          - breakpoint of the newly created breakpoint, -1 on error.
    403         num_locations - number of locations set for the breakpoint.
    404 
    405     If there is only one location, the dictionary MAY contain:
    406         file          - source file name
    407         line_no       - source line number
    408         symbol        - symbol name
    409         inline_symbol - inlined symbol name
    410         offset        - offset from the original symbol
    411         module        - module
    412         address       - address at which the breakpoint was set."""
    413 
    414     patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
    415                 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
    416                 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+), address = (?P<address>0x[0-9a-fA-F]+)$",
    417                 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"]
    418     match_object = test.match (command, patterns)
    419     break_results = match_object.groupdict()
    420 
    421     # We always insert the breakpoint number, setting it to -1 if we couldn't find it
    422     # Also, make sure it gets stored as an integer.
    423     if not 'bpno' in break_results:
    424         break_results['bpno'] = -1
    425     else:
    426         break_results['bpno'] = int(break_results['bpno'])
    427         
    428     # We always insert the number of locations
    429     # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
    430     # We also make sure it is an integer.
    431 
    432     if not 'num_locations' in break_results:
    433         num_locations = 1
    434     else:
    435         num_locations = break_results['num_locations']
    436         if num_locations == 'no':
    437             num_locations = 0
    438         else:
    439             num_locations = int(break_results['num_locations'])
    440 
    441     break_results['num_locations'] = num_locations
    442     
    443     if 'line_no' in break_results:
    444         break_results['line_no'] = int(break_results['line_no'])
    445 
    446     return break_results
    447 
    448 def get_bpno_from_match (break_results):
    449     return int (break_results['bpno'])
    450 
    451 def check_breakpoint_result (test, break_results, file_name=None, line_number=-1, symbol_name=None, symbol_match_exact=True, module_name=None, offset=-1, num_locations=-1):
    452 
    453     out_num_locations = break_results['num_locations']
    454 
    455     if num_locations == -1:
    456         test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.")
    457     else:
    458         test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations))
    459 
    460     if file_name:
    461         out_file_name = ""
    462         if 'file' in break_results:
    463             out_file_name = break_results['file']
    464         test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name))
    465 
    466     if line_number != -1:
    467         out_file_line = -1
    468         if 'line_no' in break_results:
    469             out_line_number = break_results['line_no']
    470 
    471         test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number))
    472 
    473     if symbol_name:
    474         out_symbol_name = ""
    475         # Look first for the inlined symbol name, otherwise use the symbol name:
    476         if 'inline_symbol' in break_results and break_results['inline_symbol']:
    477             out_symbol_name = break_results['inline_symbol']
    478         elif 'symbol' in break_results:
    479             out_symbol_name = break_results['symbol']
    480 
    481         if symbol_match_exact:
    482             test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name))
    483         else:
    484             test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name))
    485 
    486     if module_name:
    487         out_nodule_name = None
    488         if 'module' in break_results:
    489             out_module_name = break_results['module']
    490         
    491         test.assertTrue (module_name.find(out_module_name) != -1, "Symbol module name '%s' isn't in expected module name '%s'."%(out_module_name, module_name))
    492 
    493 # ==================================================
    494 # Utility functions related to Threads and Processes
    495 # ==================================================
    496 
    497 def get_stopped_threads(process, reason):
    498     """Returns the thread(s) with the specified stop reason in a list.
    499 
    500     The list can be empty if no such thread exists.
    501     """
    502     threads = []
    503     for t in process:
    504         if t.GetStopReason() == reason:
    505             threads.append(t)
    506     return threads
    507 
    508 def get_stopped_thread(process, reason):
    509     """A convenience function which returns the first thread with the given stop
    510     reason or None.
    511 
    512     Example usages:
    513 
    514     1. Get the stopped thread due to a breakpoint condition
    515 
    516     ...
    517         from lldbutil import get_stopped_thread
    518         thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
    519         self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
    520     ...
    521 
    522     2. Get the thread stopped due to a breakpoint
    523 
    524     ...
    525         from lldbutil import get_stopped_thread
    526         thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
    527         self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
    528     ...
    529 
    530     """
    531     threads = get_stopped_threads(process, reason)
    532     if len(threads) == 0:
    533         return None
    534     return threads[0]
    535 
    536 def get_threads_stopped_at_breakpoint (process, bkpt):
    537     """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
    538     stopped_threads = []
    539     threads = []
    540 
    541     stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
    542 
    543     if len(stopped_threads) == 0:
    544         return threads
    545     
    546     for thread in stopped_threads:
    547         # Make sure we've hit our breakpoint...
    548         break_id = thread.GetStopReasonDataAtIndex (0)
    549         if break_id == bkpt.GetID():
    550             threads.append(thread)
    551 
    552     return threads
    553 
    554 def continue_to_breakpoint (process, bkpt):
    555     """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
    556     process.Continue()
    557     if process.GetState() != lldb.eStateStopped:
    558         return None
    559     else:
    560         return get_threads_stopped_at_breakpoint (process, bkpt)
    561 
    562 def get_caller_symbol(thread):
    563     """
    564     Returns the symbol name for the call site of the leaf function.
    565     """
    566     depth = thread.GetNumFrames()
    567     if depth <= 1:
    568         return None
    569     caller = thread.GetFrameAtIndex(1).GetSymbol()
    570     if caller:
    571         return caller.GetName()
    572     else:
    573         return None
    574 
    575 
    576 def get_function_names(thread):
    577     """
    578     Returns a sequence of function names from the stack frames of this thread.
    579     """
    580     def GetFuncName(i):
    581         return thread.GetFrameAtIndex(i).GetFunctionName()
    582 
    583     return map(GetFuncName, range(thread.GetNumFrames()))
    584 
    585 
    586 def get_symbol_names(thread):
    587     """
    588     Returns a sequence of symbols for this thread.
    589     """
    590     def GetSymbol(i):
    591         return thread.GetFrameAtIndex(i).GetSymbol().GetName()
    592 
    593     return map(GetSymbol, range(thread.GetNumFrames()))
    594 
    595 
    596 def get_pc_addresses(thread):
    597     """
    598     Returns a sequence of pc addresses for this thread.
    599     """
    600     def GetPCAddress(i):
    601         return thread.GetFrameAtIndex(i).GetPCAddress()
    602 
    603     return map(GetPCAddress, range(thread.GetNumFrames()))
    604 
    605 
    606 def get_filenames(thread):
    607     """
    608     Returns a sequence of file names from the stack frames of this thread.
    609     """
    610     def GetFilename(i):
    611         return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
    612 
    613     return map(GetFilename, range(thread.GetNumFrames()))
    614 
    615 
    616 def get_line_numbers(thread):
    617     """
    618     Returns a sequence of line numbers from the stack frames of this thread.
    619     """
    620     def GetLineNumber(i):
    621         return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
    622 
    623     return map(GetLineNumber, range(thread.GetNumFrames()))
    624 
    625 
    626 def get_module_names(thread):
    627     """
    628     Returns a sequence of module names from the stack frames of this thread.
    629     """
    630     def GetModuleName(i):
    631         return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
    632 
    633     return map(GetModuleName, range(thread.GetNumFrames()))
    634 
    635 
    636 def get_stack_frames(thread):
    637     """
    638     Returns a sequence of stack frames for this thread.
    639     """
    640     def GetStackFrame(i):
    641         return thread.GetFrameAtIndex(i)
    642 
    643     return map(GetStackFrame, range(thread.GetNumFrames()))
    644 
    645 
    646 def print_stacktrace(thread, string_buffer = False):
    647     """Prints a simple stack trace of this thread."""
    648 
    649     output = StringIO.StringIO() if string_buffer else sys.stdout
    650     target = thread.GetProcess().GetTarget()
    651 
    652     depth = thread.GetNumFrames()
    653 
    654     mods = get_module_names(thread)
    655     funcs = get_function_names(thread)
    656     symbols = get_symbol_names(thread)
    657     files = get_filenames(thread)
    658     lines = get_line_numbers(thread)
    659     addrs = get_pc_addresses(thread)
    660 
    661     if thread.GetStopReason() != lldb.eStopReasonInvalid:
    662         desc =  "stop reason=" + stop_reason_to_str(thread.GetStopReason())
    663     else:
    664         desc = ""
    665     print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
    666         thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
    667 
    668     for i in range(depth):
    669         frame = thread.GetFrameAtIndex(i)
    670         function = frame.GetFunction()
    671 
    672         load_addr = addrs[i].GetLoadAddress(target)
    673         if not function:
    674             file_addr = addrs[i].GetFileAddress()
    675             start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
    676             symbol_offset = file_addr - start_addr
    677             print >> output, "  frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
    678                 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
    679         else:
    680             print >> output, "  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
    681                 num=i, addr=load_addr, mod=mods[i],
    682                 func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
    683                 file=files[i], line=lines[i],
    684                 args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
    685 
    686     if string_buffer:
    687         return output.getvalue()
    688 
    689 
    690 def print_stacktraces(process, string_buffer = False):
    691     """Prints the stack traces of all the threads."""
    692 
    693     output = StringIO.StringIO() if string_buffer else sys.stdout
    694 
    695     print >> output, "Stack traces for " + str(process)
    696 
    697     for thread in process:
    698         print >> output, print_stacktrace(thread, string_buffer=True)
    699 
    700     if string_buffer:
    701         return output.getvalue()
    702 
    703 # ===================================
    704 # Utility functions related to Frames
    705 # ===================================
    706 
    707 def get_parent_frame(frame):
    708     """
    709     Returns the parent frame of the input frame object; None if not available.
    710     """
    711     thread = frame.GetThread()
    712     parent_found = False
    713     for f in thread:
    714         if parent_found:
    715             return f
    716         if f.GetFrameID() == frame.GetFrameID():
    717             parent_found = True
    718 
    719     # If we reach here, no parent has been found, return None.
    720     return None
    721 
    722 def get_args_as_string(frame, showFuncName=True):
    723     """
    724     Returns the args of the input frame object as a string.
    725     """
    726     # arguments     => True
    727     # locals        => False
    728     # statics       => False
    729     # in_scope_only => True
    730     vars = frame.GetVariables(True, False, False, True) # type of SBValueList
    731     args = [] # list of strings
    732     for var in vars:
    733         args.append("(%s)%s=%s" % (var.GetTypeName(),
    734                                    var.GetName(),
    735                                    var.GetValue()))
    736     if frame.GetFunction():
    737         name = frame.GetFunction().GetName()
    738     elif frame.GetSymbol():
    739         name = frame.GetSymbol().GetName()
    740     else:
    741         name = ""
    742     if showFuncName:
    743         return "%s(%s)" % (name, ", ".join(args))
    744     else:
    745         return "(%s)" % (", ".join(args))
    746         
    747 def print_registers(frame, string_buffer = False):
    748     """Prints all the register sets of the frame."""
    749 
    750     output = StringIO.StringIO() if string_buffer else sys.stdout
    751 
    752     print >> output, "Register sets for " + str(frame)
    753 
    754     registerSet = frame.GetRegisters() # Return type of SBValueList.
    755     print >> output, "Frame registers (size of register set = %d):" % registerSet.GetSize()
    756     for value in registerSet:
    757         #print >> output, value 
    758         print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
    759         for child in value:
    760             print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue())
    761 
    762     if string_buffer:
    763         return output.getvalue()
    764 
    765 def get_registers(frame, kind):
    766     """Returns the registers given the frame and the kind of registers desired.
    767 
    768     Returns None if there's no such kind.
    769     """
    770     registerSet = frame.GetRegisters() # Return type of SBValueList.
    771     for value in registerSet:
    772         if kind.lower() in value.GetName().lower():
    773             return value
    774 
    775     return None
    776 
    777 def get_GPRs(frame):
    778     """Returns the general purpose registers of the frame as an SBValue.
    779 
    780     The returned SBValue object is iterable.  An example:
    781         ...
    782         from lldbutil import get_GPRs
    783         regs = get_GPRs(frame)
    784         for reg in regs:
    785             print "%s => %s" % (reg.GetName(), reg.GetValue())
    786         ...
    787     """
    788     return get_registers(frame, "general purpose")
    789 
    790 def get_FPRs(frame):
    791     """Returns the floating point registers of the frame as an SBValue.
    792 
    793     The returned SBValue object is iterable.  An example:
    794         ...
    795         from lldbutil import get_FPRs
    796         regs = get_FPRs(frame)
    797         for reg in regs:
    798             print "%s => %s" % (reg.GetName(), reg.GetValue())
    799         ...
    800     """
    801     return get_registers(frame, "floating point")
    802 
    803 def get_ESRs(frame):
    804     """Returns the exception state registers of the frame as an SBValue.
    805 
    806     The returned SBValue object is iterable.  An example:
    807         ...
    808         from lldbutil import get_ESRs
    809         regs = get_ESRs(frame)
    810         for reg in regs:
    811             print "%s => %s" % (reg.GetName(), reg.GetValue())
    812         ...
    813     """
    814     return get_registers(frame, "exception state")
    815 
    816 # ======================================
    817 # Utility classes/functions for SBValues
    818 # ======================================
    819 
    820 class BasicFormatter(object):
    821     """The basic formatter inspects the value object and prints the value."""
    822     def format(self, value, buffer=None, indent=0):
    823         if not buffer:
    824             output = StringIO.StringIO()
    825         else:
    826             output = buffer
    827         # If there is a summary, it suffices.
    828         val = value.GetSummary()
    829         # Otherwise, get the value.
    830         if val == None:
    831             val = value.GetValue()
    832         if val == None and value.GetNumChildren() > 0:
    833             val = "%s (location)" % value.GetLocation()
    834         print >> output, "{indentation}({type}) {name} = {value}".format(
    835             indentation = ' ' * indent,
    836             type = value.GetTypeName(),
    837             name = value.GetName(),
    838             value = val)
    839         return output.getvalue()
    840 
    841 class ChildVisitingFormatter(BasicFormatter):
    842     """The child visiting formatter prints the value and its immediate children.
    843 
    844     The constructor takes a keyword arg: indent_child, which defaults to 2.
    845     """
    846     def __init__(self, indent_child=2):
    847         """Default indentation of 2 SPC's for the children."""
    848         self.cindent = indent_child
    849     def format(self, value, buffer=None):
    850         if not buffer:
    851             output = StringIO.StringIO()
    852         else:
    853             output = buffer
    854 
    855         BasicFormatter.format(self, value, buffer=output)
    856         for child in value:
    857             BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
    858 
    859         return output.getvalue()
    860 
    861 class RecursiveDecentFormatter(BasicFormatter):
    862     """The recursive decent formatter prints the value and the decendents.
    863 
    864     The constructor takes two keyword args: indent_level, which defaults to 0,
    865     and indent_child, which defaults to 2.  The current indentation level is
    866     determined by indent_level, while the immediate children has an additional
    867     indentation by inden_child. 
    868     """
    869     def __init__(self, indent_level=0, indent_child=2):
    870         self.lindent = indent_level
    871         self.cindent = indent_child
    872     def format(self, value, buffer=None):
    873         if not buffer:
    874             output = StringIO.StringIO()
    875         else:
    876             output = buffer
    877 
    878         BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
    879         new_indent = self.lindent + self.cindent
    880         for child in value:
    881             if child.GetSummary() != None:
    882                 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
    883             else:
    884                 if child.GetNumChildren() > 0:
    885                     rdf = RecursiveDecentFormatter(indent_level=new_indent)
    886                     rdf.format(child, buffer=output)
    887                 else:
    888                     BasicFormatter.format(self, child, buffer=output, indent=new_indent)
    889 
    890         return output.getvalue()
    891