diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/lldbutil.py')
-rw-r--r-- | packages/Python/lldbsuite/test/lldbutil.py | 444 |
1 files changed, 320 insertions, 124 deletions
diff --git a/packages/Python/lldbsuite/test/lldbutil.py b/packages/Python/lldbsuite/test/lldbutil.py index 45e9bb407d15..7732dbe6dff3 100644 --- a/packages/Python/lldbsuite/test/lldbutil.py +++ b/packages/Python/lldbsuite/test/lldbutil.py @@ -30,6 +30,7 @@ def is_exe(fpath): """Returns True if fpath is an executable.""" return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + def which(program): """Returns the full path to a program; None otherwise.""" fpath, fname = os.path.split(program) @@ -47,6 +48,7 @@ def which(program): # Disassembly for an SBFunction or an SBSymbol object # =================================================== + def disassemble(target, function_or_symbol): """Disassemble the function or symbol given a target. @@ -62,6 +64,7 @@ def disassemble(target, function_or_symbol): # Integer (byte size 1, 2, 4, and 8) to bytearray conversion # ========================================================== + def int_to_bytearray(val, bytesize): """Utility function to convert an integer into a bytearray. @@ -87,6 +90,7 @@ def int_to_bytearray(val, bytesize): packed = struct.pack(fmt, val) return bytearray(packed) + def bytearray_to_int(bytes, bytesize): """Utility function to convert a bytearray into an integer. @@ -142,7 +146,7 @@ def get_description(obj, option=None): if not success: return None return stream.GetData() - + # ================================================= # Convert some enum value to its string counterpart @@ -177,6 +181,7 @@ def state_type_to_str(enum): else: raise Exception("Unknown StateType enum") + def stop_reason_to_str(enum): """Returns the stopReason string given an enum.""" if enum == lldb.eStopReasonInvalid: @@ -202,6 +207,7 @@ def stop_reason_to_str(enum): else: raise Exception("Unknown StopReason enum") + def symbol_type_to_str(enum): """Returns the symbolType string given an enum.""" if enum == lldb.eSymbolTypeInvalid: @@ -253,6 +259,7 @@ def symbol_type_to_str(enum): elif enum == lldb.eSymbolTypeUndefined: return "undefined" + def value_type_to_str(enum): """Returns the valueType string given an enum.""" if enum == lldb.eValueTypeInvalid: @@ -280,12 +287,12 @@ def value_type_to_str(enum): # ================================================== def sort_stopped_threads(process, - breakpoint_threads = None, - crashed_threads = None, - watchpoint_threads = None, - signal_threads = None, - exiting_threads = None, - other_threads = None): + breakpoint_threads=None, + crashed_threads=None, + watchpoint_threads=None, + signal_threads=None, + exiting_threads=None, + other_threads=None): """ Fills array *_threads with threads stopped for the corresponding stop reason. """ @@ -314,8 +321,16 @@ def sort_stopped_threads(process, # Utility functions for setting breakpoints # ================================================== -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): - """Set a breakpoint by file and line, returning the breakpoint number. + +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): + """Set a breakpoint by file and line, returning the breakpoint number. If extra_options is not None, then we append it to the breakpoint set command. @@ -323,10 +338,10 @@ def run_break_set_by_file_and_line (test, file_name, line_number, extra_options If loc_exact is true, we check that there is one location, and that location must be at the input file and line number.""" - if file_name == None: - command = 'breakpoint set -l %d'%(line_number) + if file_name is None: + command = 'breakpoint set -l %d' % (line_number) else: - command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number) + command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number) if module_name: command += " --shlib '%s'" % (module_name) @@ -334,20 +349,36 @@ def run_break_set_by_file_and_line (test, file_name, line_number, extra_options if extra_options: command += " " + extra_options - break_results = run_break_set_command (test, command) + break_results = run_break_set_command(test, command) if num_expected_locations == 1 and loc_exact: - check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations, + file_name=file_name, + line_number=line_number, + module_name=module_name) else: - check_breakpoint_result (test, break_results, num_locations = num_expected_locations) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations) + + return get_bpno_from_match(break_results) - return get_bpno_from_match (break_results) -def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None): +def run_break_set_by_symbol( + test, + symbol, + extra_options=None, + num_expected_locations=-1, + sym_exact=False, + module_name=None): """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line. If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match.""" - command = 'breakpoint set -n "%s"'%(symbol) + command = 'breakpoint set -n "%s"' % (symbol) if module_name: command += " --shlib '%s'" % (module_name) @@ -355,16 +386,30 @@ def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_lo if extra_options: command += " " + extra_options - break_results = run_break_set_command (test, command) + break_results = run_break_set_command(test, command) if num_expected_locations == 1 and sym_exact: - check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations, + symbol_name=symbol, + module_name=module_name) else: - check_breakpoint_result (test, break_results, num_locations = num_expected_locations) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations) - return get_bpno_from_match (break_results) + return get_bpno_from_match(break_results) -def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None): + +def run_break_set_by_selector( + test, + selector, + extra_options=None, + num_expected_locations=-1, + module_name=None): """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line.""" command = 'breakpoint set -S "%s"' % (selector) @@ -375,42 +420,68 @@ def run_break_set_by_selector (test, selector, extra_options = None, num_expecte if extra_options: command += " " + extra_options - break_results = run_break_set_command (test, command) + break_results = run_break_set_command(test, command) if num_expected_locations == 1: - check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations, + symbol_name=selector, + symbol_match_exact=False, + module_name=module_name) else: - check_breakpoint_result (test, break_results, num_locations = num_expected_locations) + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations) + + return get_bpno_from_match(break_results) - return get_bpno_from_match (break_results) -def run_break_set_by_regexp (test, regexp, extra_options=None, num_expected_locations=-1): +def run_break_set_by_regexp( + test, + regexp, + extra_options=None, + num_expected_locations=-1): """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line.""" - command = 'breakpoint set -r "%s"'%(regexp) + command = 'breakpoint set -r "%s"' % (regexp) if extra_options: command += " " + extra_options - - break_results = run_break_set_command (test, command) - - check_breakpoint_result (test, break_results, num_locations=num_expected_locations) - return get_bpno_from_match (break_results) + break_results = run_break_set_command(test, command) -def run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1): + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations) + + return get_bpno_from_match(break_results) + + +def run_break_set_by_source_regexp( + test, + regexp, + extra_options=None, + num_expected_locations=-1): """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line.""" - command = 'breakpoint set -p "%s"'%(regexp) + command = 'breakpoint set -p "%s"' % (regexp) if extra_options: command += " " + extra_options - - break_results = run_break_set_command (test, command) - - check_breakpoint_result (test, break_results, num_locations=num_expected_locations) - return get_bpno_from_match (break_results) + break_results = run_break_set_command(test, command) + + check_breakpoint_result( + test, + break_results, + num_locations=num_expected_locations) -def run_break_set_command (test, command): - """Run the command passed in - it must be some break set variant - and analyze the result. + return get_bpno_from_match(break_results) + + +def run_break_set_command(test, command): + """Run the command passed in - it must be some break set variant - and analyze the result. Returns a dictionary of information gleaned from the command-line results. Will assert if the breakpoint setting fails altogether. @@ -427,11 +498,12 @@ def run_break_set_command (test, command): module - module address - address at which the breakpoint was set.""" - patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$", - r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.", - 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]+)$", - 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]+)$"] - match_object = test.match (command, patterns) + patterns = [ + r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$", + r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.", + 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]+)$", + 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]+)$"] + match_object = test.match(command, patterns) break_results = match_object.groupdict() # We always insert the breakpoint number, setting it to -1 if we couldn't find it @@ -440,7 +512,7 @@ def run_break_set_command (test, command): break_results['bpno'] = -1 else: break_results['bpno'] = int(break_results['bpno']) - + # We always insert the number of locations # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1... # We also make sure it is an integer. @@ -455,61 +527,101 @@ def run_break_set_command (test, command): num_locations = int(break_results['num_locations']) break_results['num_locations'] = num_locations - + if 'line_no' in break_results: break_results['line_no'] = int(break_results['line_no']) return break_results -def get_bpno_from_match (break_results): - return int (break_results['bpno']) -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): +def get_bpno_from_match(break_results): + return int(break_results['bpno']) + + +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): out_num_locations = break_results['num_locations'] if num_locations == -1: - test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.") + test.assertTrue(out_num_locations > 0, + "Expecting one or more locations, got none.") else: - test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations)) + test.assertTrue( + num_locations == out_num_locations, + "Expecting %d locations, got %d." % + (num_locations, + out_num_locations)) if file_name: out_file_name = "" if 'file' in break_results: out_file_name = break_results['file'] - test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name)) + test.assertTrue( + file_name == out_file_name, + "Breakpoint file name '%s' doesn't match resultant name '%s'." % + (file_name, + out_file_name)) if line_number != -1: out_line_number = -1 if 'line_no' in break_results: out_line_number = break_results['line_no'] - test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number)) + test.assertTrue( + line_number == out_line_number, + "Breakpoint line number %s doesn't match resultant line %s." % + (line_number, + out_line_number)) if symbol_name: out_symbol_name = "" - # Look first for the inlined symbol name, otherwise use the symbol name: + # Look first for the inlined symbol name, otherwise use the symbol + # name: if 'inline_symbol' in break_results and break_results['inline_symbol']: out_symbol_name = break_results['inline_symbol'] elif 'symbol' in break_results: out_symbol_name = break_results['symbol'] if symbol_match_exact: - test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name)) + test.assertTrue( + symbol_name == out_symbol_name, + "Symbol name '%s' doesn't match resultant symbol '%s'." % + (symbol_name, + out_symbol_name)) else: - test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name)) + test.assertTrue( + out_symbol_name.find(symbol_name) != - + 1, + "Symbol name '%s' isn't in resultant symbol '%s'." % + (symbol_name, + out_symbol_name)) if module_name: out_module_name = None if 'module' in break_results: out_module_name = break_results['module'] - - 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)) + + 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)) # ================================================== # Utility functions related to Threads and Processes # ================================================== + def get_stopped_threads(process, reason): """Returns the thread(s) with the specified stop reason in a list. @@ -521,6 +633,7 @@ def get_stopped_threads(process, reason): threads.append(t) return threads + def get_stopped_thread(process, reason): """A convenience function which returns the first thread with the given stop reason or None. @@ -549,28 +662,32 @@ def get_stopped_thread(process, reason): return None return threads[0] + def get_threads_stopped_at_breakpoint_id(process, bpid): """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" stopped_threads = [] threads = [] - stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint) + stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint) if len(stopped_threads) == 0: return threads - + for thread in stopped_threads: # Make sure we've hit our breakpoint... - break_id = thread.GetStopReasonDataAtIndex (0) + break_id = thread.GetStopReasonDataAtIndex(0) if break_id == bpid: threads.append(thread) return threads -def get_threads_stopped_at_breakpoint (process, bkpt): + +def get_threads_stopped_at_breakpoint(process, bkpt): return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID()) -def get_one_thread_stopped_at_breakpoint_id(process, bpid, require_exactly_one = True): + +def get_one_thread_stopped_at_breakpoint_id( + process, bpid, require_exactly_one=True): threads = get_threads_stopped_at_breakpoint_id(process, bpid) if len(threads) == 0: return None @@ -579,20 +696,27 @@ def get_one_thread_stopped_at_breakpoint_id(process, bpid, require_exactly_one = return threads[0] -def get_one_thread_stopped_at_breakpoint(process, bkpt, require_exactly_one = True): - return get_one_thread_stopped_at_breakpoint_id(process, bkpt.GetID(), require_exactly_one) -def is_thread_crashed (test, thread): +def get_one_thread_stopped_at_breakpoint( + process, bkpt, require_exactly_one=True): + return get_one_thread_stopped_at_breakpoint_id( + process, bkpt.GetID(), require_exactly_one) + + +def is_thread_crashed(test, thread): """In the test suite we dereference a null pointer to simulate a crash. The way this is reported depends on the platform.""" if test.platformIsDarwin(): - return thread.GetStopReason() == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100) + return thread.GetStopReason( + ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100) elif test.getPlatform() == "linux": - return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV") + return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex( + 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV") else: return "invalid address" in thread.GetStopDescription(100) -def get_crashed_threads (test, process): + +def get_crashed_threads(test, process): threads = [] if process.GetState() != lldb.eStateStopped: return threads @@ -601,13 +725,15 @@ def get_crashed_threads (test, process): threads.append(thread) return threads -def continue_to_breakpoint (process, bkpt): + +def continue_to_breakpoint(process, bkpt): """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" process.Continue() if process.GetState() != lldb.eStateStopped: return None else: - return get_threads_stopped_at_breakpoint (process, bkpt) + return get_threads_stopped_at_breakpoint(process, bkpt) + def get_caller_symbol(thread): """ @@ -658,7 +784,8 @@ def get_filenames(thread): Returns a sequence of file names from the stack frames of this thread. """ def GetFilename(i): - return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename() + return thread.GetFrameAtIndex( + i).GetLineEntry().GetFileSpec().GetFilename() return list(map(GetFilename, list(range(thread.GetNumFrames())))) @@ -678,7 +805,8 @@ def get_module_names(thread): Returns a sequence of module names from the stack frames of this thread. """ def GetModuleName(i): - return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename() + return thread.GetFrameAtIndex( + i).GetModule().GetFileSpec().GetFilename() return list(map(GetModuleName, list(range(thread.GetNumFrames())))) @@ -693,7 +821,7 @@ def get_stack_frames(thread): return list(map(GetStackFrame, list(range(thread.GetNumFrames())))) -def print_stacktrace(thread, string_buffer = False): +def print_stacktrace(thread, string_buffer=False): """Prints a simple stack trace of this thread.""" output = SixStringIO() if string_buffer else sys.stdout @@ -709,11 +837,15 @@ def print_stacktrace(thread, string_buffer = False): addrs = get_pc_addresses(thread) if thread.GetStopReason() != lldb.eStopReasonInvalid: - desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) + desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) else: desc = "" - print("Stack trace for thread id={0:#x} name={1} queue={2} ".format( - thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc, file=output) + print( + "Stack trace for thread id={0:#x} name={1} queue={2} ".format( + thread.GetThreadID(), + thread.GetName(), + thread.GetQueueName()) + desc, + file=output) for i in range(depth): frame = thread.GetFrameAtIndex(i) @@ -724,20 +856,34 @@ def print_stacktrace(thread, string_buffer = False): file_addr = addrs[i].GetFileAddress() start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress() symbol_offset = file_addr - start_addr - print(" frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( - num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset), file=output) + print( + " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( + num=i, + addr=load_addr, + mod=mods[i], + symbol=symbols[i], + offset=symbol_offset), + file=output) else: - print(" frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( - num=i, addr=load_addr, mod=mods[i], - func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i], - file=files[i], line=lines[i], - args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()'), file=output) + print( + " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( + num=i, + addr=load_addr, + mod=mods[i], + func='%s [inlined]' % + funcs[i] if frame.IsInlined() else funcs[i], + file=files[i], + line=lines[i], + args=get_args_as_string( + frame, + showFuncName=False) if not frame.IsInlined() else '()'), + file=output) if string_buffer: return output.getvalue() -def print_stacktraces(process, string_buffer = False): +def print_stacktraces(process, string_buffer=False): """Prints the stack traces of all the threads.""" output = SixStringIO() if string_buffer else sys.stdout @@ -750,16 +896,21 @@ def print_stacktraces(process, string_buffer = False): if string_buffer: return output.getvalue() -def expect_state_changes(test, listener, process, states, timeout = 5): + +def expect_state_changes(test, listener, process, states, timeout=5): """Listens for state changed events on the listener and makes sure they match what we expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" for expected_state in states: def get_next_event(): event = lldb.SBEvent() - if not listener.WaitForEventForBroadcasterWithType(timeout, process.GetBroadcaster(), - lldb.SBProcess.eBroadcastBitStateChanged, event): - test.fail("Timed out while waiting for a transition to state %s" % + if not listener.WaitForEventForBroadcasterWithType( + timeout, + process.GetBroadcaster(), + lldb.SBProcess.eBroadcastBitStateChanged, + event): + test.fail( + "Timed out while waiting for a transition to state %s" % lldb.SBDebugger.StateAsCString(expected_state)) return event @@ -768,16 +919,21 @@ def expect_state_changes(test, listener, process, states, timeout = 5): lldb.SBProcess.GetRestartedFromEvent(event)): # Ignore restarted event and the subsequent running event. event = get_next_event() - test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), lldb.eStateRunning, - "Restarted event followed by a running event") + test.assertEqual( + lldb.SBProcess.GetStateFromEvent(event), + lldb.eStateRunning, + "Restarted event followed by a running event") event = get_next_event() - test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), expected_state) + test.assertEqual( + lldb.SBProcess.GetStateFromEvent(event), + expected_state) # =================================== # Utility functions related to Frames # =================================== + def get_parent_frame(frame): """ Returns the parent frame of the input frame object; None if not available. @@ -793,6 +949,7 @@ def get_parent_frame(frame): # If we reach here, no parent has been found, return None. return None + def get_args_as_string(frame, showFuncName=True): """ Returns the args of the input frame object as a string. @@ -801,8 +958,8 @@ def get_args_as_string(frame, showFuncName=True): # locals => False # statics => False # in_scope_only => True - vars = frame.GetVariables(True, False, False, True) # type of SBValueList - args = [] # list of strings + vars = frame.GetVariables(True, False, False, True) # type of SBValueList + args = [] # list of strings for var in vars: args.append("(%s)%s=%s" % (var.GetTypeName(), var.GetName(), @@ -817,37 +974,46 @@ def get_args_as_string(frame, showFuncName=True): return "%s(%s)" % (name, ", ".join(args)) else: return "(%s)" % (", ".join(args)) - -def print_registers(frame, string_buffer = False): + + +def print_registers(frame, string_buffer=False): """Prints all the register sets of the frame.""" output = SixStringIO() if string_buffer else sys.stdout print("Register sets for " + str(frame), file=output) - registerSet = frame.GetRegisters() # Return type of SBValueList. - print("Frame registers (size of register set = %d):" % registerSet.GetSize(), file=output) + registerSet = frame.GetRegisters() # Return type of SBValueList. + print("Frame registers (size of register set = %d):" % + registerSet.GetSize(), file=output) for value in registerSet: #print(value, file=output) - print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()), file=output) + print("%s (number of children = %d):" % + (value.GetName(), value.GetNumChildren()), file=output) for child in value: - print("Name: %s, Value: %s" % (child.GetName(), child.GetValue()), file=output) + print( + "Name: %s, Value: %s" % + (child.GetName(), + child.GetValue()), + file=output) if string_buffer: return output.getvalue() + def get_registers(frame, kind): """Returns the registers given the frame and the kind of registers desired. Returns None if there's no such kind. """ - registerSet = frame.GetRegisters() # Return type of SBValueList. + registerSet = frame.GetRegisters() # Return type of SBValueList. for value in registerSet: if kind.lower() in value.GetName().lower(): return value return None + def get_GPRs(frame): """Returns the general purpose registers of the frame as an SBValue. @@ -861,6 +1027,7 @@ def get_GPRs(frame): """ return get_registers(frame, "general purpose") + def get_FPRs(frame): """Returns the floating point registers of the frame as an SBValue. @@ -874,6 +1041,7 @@ def get_FPRs(frame): """ return get_registers(frame, "floating point") + def get_ESRs(frame): """Returns the exception state registers of the frame as an SBValue. @@ -891,8 +1059,10 @@ def get_ESRs(frame): # Utility classes/functions for SBValues # ====================================== + class BasicFormatter(object): """The basic formatter inspects the value object and prints the value.""" + def format(self, value, buffer=None, indent=0): if not buffer: output = SixStringIO() @@ -901,25 +1071,28 @@ class BasicFormatter(object): # If there is a summary, it suffices. val = value.GetSummary() # Otherwise, get the value. - if val == None: + if val is None: val = value.GetValue() - if val == None and value.GetNumChildren() > 0: + if val is None and value.GetNumChildren() > 0: val = "%s (location)" % value.GetLocation() print("{indentation}({type}) {name} = {value}".format( - indentation = ' ' * indent, - type = value.GetTypeName(), - name = value.GetName(), - value = val), file=output) + indentation=' ' * indent, + type=value.GetTypeName(), + name=value.GetName(), + value=val), file=output) return output.getvalue() + class ChildVisitingFormatter(BasicFormatter): """The child visiting formatter prints the value and its immediate children. The constructor takes a keyword arg: indent_child, which defaults to 2. """ + def __init__(self, indent_child=2): """Default indentation of 2 SPC's for the children.""" self.cindent = indent_child + def format(self, value, buffer=None): if not buffer: output = SixStringIO() @@ -928,21 +1101,25 @@ class ChildVisitingFormatter(BasicFormatter): BasicFormatter.format(self, value, buffer=output) for child in value: - BasicFormatter.format(self, child, buffer=output, indent=self.cindent) + BasicFormatter.format( + self, child, buffer=output, indent=self.cindent) return output.getvalue() + class RecursiveDecentFormatter(BasicFormatter): """The recursive decent formatter prints the value and the decendents. The constructor takes two keyword args: indent_level, which defaults to 0, and indent_child, which defaults to 2. The current indentation level is determined by indent_level, while the immediate children has an additional - indentation by inden_child. + indentation by inden_child. """ + def __init__(self, indent_level=0, indent_child=2): self.lindent = indent_level self.cindent = indent_child + def format(self, value, buffer=None): if not buffer: output = SixStringIO() @@ -952,14 +1129,16 @@ class RecursiveDecentFormatter(BasicFormatter): BasicFormatter.format(self, value, buffer=output, indent=self.lindent) new_indent = self.lindent + self.cindent for child in value: - if child.GetSummary() != None: - BasicFormatter.format(self, child, buffer=output, indent=new_indent) + if child.GetSummary() is not None: + BasicFormatter.format( + self, child, buffer=output, indent=new_indent) else: if child.GetNumChildren() > 0: rdf = RecursiveDecentFormatter(indent_level=new_indent) rdf.format(child, buffer=output) else: - BasicFormatter.format(self, child, buffer=output, indent=new_indent) + BasicFormatter.format( + self, child, buffer=output, indent=new_indent) return output.getvalue() @@ -967,12 +1146,14 @@ class RecursiveDecentFormatter(BasicFormatter): # Utility functions for path manipulation on remote platforms # =========================================================== + def join_remote_paths(*paths): # TODO: update with actual platform name for remote windows once it exists if lldb.remote_platform.GetName() == 'remote-windows': return os.path.join(*paths).replace(os.path.sep, '\\') return os.path.join(*paths).replace(os.path.sep, '/') + def append_to_process_working_directory(*paths): remote = lldb.remote_platform if remote: @@ -985,6 +1166,7 @@ def append_to_process_working_directory(*paths): import signal + def get_signal_number(signal_name): platform = lldb.remote_platform if platform and platform.IsValid(): @@ -996,20 +1178,23 @@ def get_signal_number(signal_name): # No remote platform; fall back to using local python signals. return getattr(signal, signal_name) + class PrintableRegex(object): + def __init__(self, text): self.regex = re.compile(text) self.text = text - + def match(self, str): return self.regex.match(str) - + def __str__(self): return "%s" % (self.text) - + def __repr__(self): return "re.compile(%s) -> %s" % (self.text, self.regex) + def skip_if_callable(test, mycallable, reason): if six.callable(mycallable): if mycallable(test): @@ -1017,6 +1202,7 @@ def skip_if_callable(test, mycallable, reason): return True return False + def skip_if_library_missing(test, target, library): def find_library(target, library): for module in target.modules: @@ -1028,11 +1214,18 @@ def skip_if_library_missing(test, target, library): if library.match(filename): return False return True + def find_library_callable(test): return find_library(target, library) - return skip_if_callable(test, find_library_callable, "could not find library matching '%s' in target %s" % (library, target)) + return skip_if_callable( + test, + find_library_callable, + "could not find library matching '%s' in target %s" % + (library, + target)) + -def wait_for_file_on_target(testcase, file_path, max_attempts = 6): +def wait_for_file_on_target(testcase, file_path, max_attempts=6): for i in range(max_attempts): err, retcode, msg = testcase.run_platform_command("ls %s" % file_path) if err.Success() and retcode == 0: @@ -1042,10 +1235,13 @@ def wait_for_file_on_target(testcase, file_path, max_attempts = 6): import time time.sleep(pow(2, i) * 0.25) else: - testcase.fail("File %s not found even after %d attempts." % (file_path, max_attempts)) + testcase.fail( + "File %s not found even after %d attempts." % + (file_path, max_attempts)) err, retcode, data = testcase.run_platform_command("cat %s" % (file_path)) - testcase.assertTrue(err.Success() and retcode == 0, - "Failed to read file %s: %s, retcode: %d" % (file_path, err.GetCString(), retcode)) + testcase.assertTrue( + err.Success() and retcode == 0, "Failed to read file %s: %s, retcode: %d" % + (file_path, err.GetCString(), retcode)) return data |