Example #1
0
def reverse_watch(dbg, s_expr):
    """Perform 'reverse-watch' command on expression.
    'dbg' is the instance of ReversibleDebugger on which to operate."""
    s_expr_val = dbg.evaluate_expression(s_expr)
    fredutil.fred_debug("RW: Starting with expr value '%s'" % s_expr_val)
    # Find starting checkpoint using binary search:
    binary_search._binary_search_checkpoints(dbg, s_expr, s_expr_val)

    # STILL TESTING:  When "else" branch works well, it will become permanent,
    #  and the remaining branch of "if" can be removed.
    if False:
        dbg.current_checkpoint().set_history(
            binary_search._binary_search_history(dbg,
              dbg.copy_current_checkpoint_history(),
              0, s_expr, s_expr_val))
    else:
        if dbg.branch.get_num_checkpoints() == 0:
            fredutil.fred_error("No checkpoints found for reverse-watch.")
            return
        l_history_copy = dbg.copy_current_checkpoint_history()
        try:
	    dbg.current_checkpoint().set_history(
                binary_search.NEW_binary_search_since_last_checkpoint(dbg, l_history_copy,
                                                               0, s_expr, s_expr_val))
        except binary_search.BinarySearchTooFarAtStartError:
	    fredutil.fred_debug("BinarySearchTooFarAtStartError handled")
            fredutil.fred_info(
	        'reverse-watch failed; expr "%s"\n  is same at start and end.'
		% s_expr )
    dbg.update_state()
    fredutil.fred_debug("Reverse watch finished.")
Example #2
0
def reverse_watch(dbg, s_expr):
    """Perform 'reverse-watch' command on expression.
    'dbg' is the instance of ReversibleDebugger on which to operate."""
    s_expr_val = dbg.evaluate_expression(s_expr)
    fredutil.fred_debug("RW: Starting with expr value '%s'" % s_expr_val)
    # Find starting checkpoint using binary search:
    binary_search._binary_search_checkpoints(dbg, s_expr, s_expr_val)

    # STILL TESTING:  When "else" branch works well, it will become permanent,
    #  and the remaining branch of "if" can be removed.
    if False:
        dbg.current_checkpoint().set_history(
            binary_search._binary_search_history(
                dbg, dbg.copy_current_checkpoint_history(), 0, s_expr,
                s_expr_val))
    else:
        if dbg.branch.get_num_checkpoints() == 0:
            fredutil.fred_error("No checkpoints found for reverse-watch.")
            return
        l_history_copy = dbg.copy_current_checkpoint_history()
        try:
            dbg.current_checkpoint().set_history(
                binary_search.NEW_binary_search_since_last_checkpoint(
                    dbg, l_history_copy, 0, s_expr, s_expr_val))
        except binary_search.BinarySearchTooFarAtStartError:
            fredutil.fred_debug("BinarySearchTooFarAtStartError handled")
            fredutil.fred_info(
                'reverse-watch failed; expr "%s"\n  is same at start and end.'
                % s_expr)
    dbg.update_state()
    fredutil.fred_debug("Reverse watch finished.")
Example #3
0
def reverse_watch_with_log_support(dbg, s_expr):
    """Perform 'reverse-watch' with support from fred_command."""
    s_expr_val = dbg.evaluate_expression(s_expr)
    fredutil.fred_debug("RW: Starting with expr value '%s'" % s_expr_val)
    # Find starting checkpoint using binary search:
    binary_search._binary_search_checkpoints(dbg, s_expr, s_expr_val)
    dbg.current_checkpoint().set_history(
        binary_search._binary_search_with_log(dbg, s_expr, s_expr_val))
    dbg.update_state()
    fredutil.fred_debug("Reverse watch finished.")
Example #4
0
def reverse_watch_for_mt(dbg, s_expr):
    """Perform 'reverse-watch' command on expression, with support for
    an expression changing in a thread which is not the main thread."""
    fredutil.fred_timer_start("reverse-watch")
    if dbg.branch.get_num_checkpoints() == 0:
        fredutil.fred_error("No checkpoints found for reverse-watch.")
        return

    s_expr_val = dbg.evaluate_expression(s_expr)
    testIfTooFar = lambda: dbg.test_expression(s_expr, s_expr_val)
    fredutil.fred_debug("RW: Starting with expr value '%s'" % s_expr_val)

    # ---------------------------- Binary search of checkpoints
    if dbg.branch.get_num_checkpoints() > 1:
        # Find starting checkpoint using binary search:
        binary_search._binary_search_checkpoints(dbg, s_expr, s_expr_val)

    # ---------------------------- Binary search on the main thread
    if _reverse_watch_main_thread(dbg, s_expr, s_expr_val):
        fredutil.fred_debug("Main thread changed expression.")
        fredutil.fred_debug("Reverse-watch finished.")
        fredutil.fred_assert(not testIfTooFar())
        return

    # If we're here, it means a secondary thread caused expr to change.
    fredutil.fred_debug("Secondary thread caused expr to change. "
                        "Starting binary search of system calls.")

    # ---------------------------- Binary search through system calls
    binary_search.binary_search_log_events(dbg, testIfTooFar)
    # We are now at a point in time where at some point after the next
    # system call the expression will change. We are guaranteed that
    # the culprit thread is alive, because a "pthread_create" call is
    # an event in the system call log, and the binary search will
    # consider that in determining the lower bound.

    # ---------------------------- Round-robin search for culprit thread
    if not _reverse_watch_round_robin(dbg, testIfTooFar):
        fredutil.fred_error("Reverse-watch failed to determine the thread "
                            "which caused the expression '%s' to change." %
                            s_expr)
        return

    # At this point, whatever thread we are currently in is the correct thread.
    fredutil.fred_debug("Identified thread %d as the one changing expr." %
                        dbg.get_current_thread())
    fredutil.fred_assert(not testIfTooFar())
    dbg.current_checkpoint().set_history(
        binary_search._binary_search_regular_next_expansion(dbg, testIfTooFar))
    dbg.update_state()
    fredutil.fred_assert(not testIfTooFar())
    fredutil.fred_debug("Reverse watch finished.")
    fredutil.fred_timer_stop("reverse-watch")
    dbg.report_timing_statistics()
    return