Esempio n. 1
0
MR_Next
MR_trace_cmd_forward(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    cmd->MR_trace_strict = MR_TRUE;
    cmd->MR_trace_print_level_specified = MR_FALSE;
    cmd->MR_trace_print_level = MR_default_print_level;
    MR_init_trace_check_integrity(cmd);
    if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
        // The usage message has already been printed.
        ;
    } else if (word_count == 1) {
        MR_TracePort    port;

        port = event_info->MR_trace_port;
        if (port == MR_PORT_FAIL ||
            port == MR_PORT_REDO ||
            port == MR_PORT_EXCEPTION)
        {
            cmd->MR_trace_cmd = MR_CMD_RESUME_FORWARD;
            return STOP_INTERACTING;
        } else {
            MR_trace_do_noop();
        }
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Esempio n. 2
0
MR_Next
MR_trace_cmd_fail(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Determinism      detism;
    MR_Unsigned         depth;
    MR_Unsigned         stop_depth;
    MR_Unsigned         n;

    detism = event_info->MR_event_sll->MR_sll_entry->MR_sle_detism;
    depth = event_info->MR_call_depth;

    cmd->MR_trace_strict = MR_TRUE;
    cmd->MR_trace_print_level_specified = MR_FALSE;
    cmd->MR_trace_print_level = MR_default_print_level;
    MR_init_trace_check_integrity(cmd);
    if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
        // The usage message has already been printed.
        return KEEP_INTERACTING;
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        stop_depth = depth - n;
    } else if (word_count == 1) {
        stop_depth = depth;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    if (MR_DETISM_DET_STACK(detism)) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
            "selected procedure has determinism %s.\n",
            MR_detism_names[detism]);
        return KEEP_INTERACTING;
    }

    // A procedure that lives on the nondet stack cannot have its stack frame
    // reused by tail recursive calls (at least not when any kind of debugging
    // is enabled).

    if (depth == stop_depth && event_info->MR_trace_port == MR_PORT_FAIL) {
        MR_trace_do_noop();
    } else if (depth == stop_depth &&
        event_info->MR_trace_port == MR_PORT_EXCEPTION)
    {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
            "the call has raised an exception.\n");
    } else {
        cmd->MR_trace_cmd = MR_CMD_FAIL;
        cmd->MR_trace_stop_depth = stop_depth;
        return STOP_INTERACTING;
    }

    return KEEP_INTERACTING;
}
Esempio n. 3
0
MR_Next
MR_trace_cmd_next(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    const MR_ProcLayout     *proc_layout;
    const MR_LabelLayout    *ancestor_layout;
    MR_Unsigned             depth;
    MR_Unsigned             stop_depth;
    MR_Unsigned             n;
    MR_TracePort            port;
    MR_Word                 *base_sp;
    MR_Word                 *base_curfr;
    MR_Unsigned             reused_frames;
    MR_Level                actual_level;
    const char              *problem;       // Not used.

    depth = event_info->MR_call_depth;
    cmd->MR_trace_strict = MR_TRUE;
    cmd->MR_trace_print_level_specified = MR_FALSE;
    cmd->MR_trace_print_level = MR_default_print_level;
    MR_init_trace_check_integrity(cmd);
    if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
        // The usage message has already been printed.
        ;
        return KEEP_INTERACTING;
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        stop_depth = depth - n;
    } else if (word_count == 1) {
        n = 0;
        stop_depth = depth;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    base_sp = MR_saved_sp(event_info->MR_saved_regs);
    base_curfr = MR_saved_curfr(event_info->MR_saved_regs);
    proc_layout = event_info->MR_event_sll->MR_sll_entry;
    MR_trace_find_reused_frames(proc_layout, base_sp, reused_frames);
    port = event_info->MR_trace_port;

    if (depth == stop_depth &&
        (MR_port_is_final(port) || port == MR_PORT_TAILREC_CALL))
    {
        MR_trace_do_noop();
    } else if (depth - reused_frames <= stop_depth && stop_depth < depth) {
        MR_trace_do_noop_tail_rec();
    } else {
        ancestor_layout = MR_find_nth_ancestor(event_info->MR_event_sll,
            n, &base_sp, &base_curfr, &actual_level, &problem);
        if (ancestor_layout == NULL) {
            fflush(MR_mdb_out);
            if (problem != NULL) {
                fprintf(MR_mdb_err, "mdb: %s\n", problem);
            } else {
                fprintf(MR_mdb_err, "mdb: not that many ancestors.\n");
            }
            return KEEP_INTERACTING;
        } else if (actual_level != n) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err,
                "mdb: that stack frame has been reused, "
                "will stop in reusing call.\n");
        } else {
            cmd->MR_trace_cmd = MR_CMD_NEXT;
            cmd->MR_trace_stop_depth = stop_depth;
            return STOP_INTERACTING;
        }
    }

    return KEEP_INTERACTING;
}
Esempio n. 4
0
MR_Next
MR_trace_cmd_finish(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    const MR_ProcLayout     *proc_layout;
    const MR_LabelLayout    *ancestor_layout;
    MR_Unsigned             depth;
    MR_Unsigned             stop_depth;
    MR_Unsigned             n;
    MR_Level                ancestor_level;
    MR_TracePort            port;
    MR_Word                 *base_sp;
    MR_Word                 *base_curfr;
    MR_Unsigned             reused_frames;
    MR_Level                actual_level;
    const char              *problem;       // Not used.

    depth = event_info->MR_call_depth;
    cmd->MR_trace_strict = MR_TRUE;
    cmd->MR_trace_print_level_specified = MR_FALSE;
    cmd->MR_trace_print_level = MR_default_print_level;
    MR_init_trace_check_integrity(cmd);
    if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
        // The usage message has already been printed.
        ;
        return KEEP_INTERACTING;
    } else if (word_count == 2 &&
        ( MR_streq(words[1], "entry") || MR_streq(words[1], "clentry")))
    {
        if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_FRAME,
            &ancestor_level))
        {
            // The error message has already been printed.
            return KEEP_INTERACTING;
        }
    } else if (word_count == 2 && MR_streq(words[1], "clparent"))
    {
        if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_PARENT_FRAME,
            &ancestor_level))
        {
            // The error message has already been printed.
            return KEEP_INTERACTING;
        }
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        ancestor_level = n;
    } else if (word_count == 1) {
        ancestor_level = 0;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    base_sp = MR_saved_sp(event_info->MR_saved_regs);
    base_curfr = MR_saved_curfr(event_info->MR_saved_regs);
    proc_layout = event_info->MR_event_sll->MR_sll_entry;
    MR_trace_find_reused_frames(proc_layout, base_sp, reused_frames);
    port = event_info->MR_trace_port;

    stop_depth = depth - ancestor_level;
    if (MR_port_is_final(port) && depth == stop_depth) {
        MR_trace_do_noop();
    } else if (MR_port_is_final(port) &&
        depth - reused_frames <= stop_depth && stop_depth < depth)
    {
        MR_trace_do_noop_tail_rec();
    } else {
        ancestor_layout = MR_find_nth_ancestor(event_info->MR_event_sll,
            ancestor_level, &base_sp, &base_curfr, &actual_level, &problem);
        if (ancestor_layout == NULL) {
            fflush(MR_mdb_out);
            if (problem != NULL) {
                fprintf(MR_mdb_err, "mdb: %s\n", problem);
            } else {
                fprintf(MR_mdb_err, "mdb: not that many ancestors.\n");
            }
            return KEEP_INTERACTING;
        } else if (actual_level != ancestor_level) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err, "%d %d\n",
                (int) ancestor_level, (int) actual_level);
            fprintf(MR_mdb_err,
                "mdb: that stack frame has been reused, "
                "will stop at finish of reusing call.\n");
        } else {
            cmd->MR_trace_cmd = MR_CMD_FINISH;
            cmd->MR_trace_stop_depth = stop_depth;
            return STOP_INTERACTING;
        }
    }

    return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_retry(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Level            n;
    MR_Level            ancestor_level;
    MR_RetryAcrossIo    across_io;
    const char          *problem;
    MR_RetryResult      result;
    MR_bool             assume_all_io_is_tabled;
    MR_bool             unsafe_retry;

    ancestor_level = 0;
    across_io = MR_RETRY_IO_INTERACTIVE;
    assume_all_io_is_tabled = MR_FALSE;
    if (! MR_trace_options_retry(&across_io, &assume_all_io_is_tabled,
        &words, &word_count))
    {
        ; /* the usage message has already been printed */
    } else if (word_count == 2 &&
        ( MR_streq(words[1], "clique") || MR_streq(words[1], "clentry")))
    {
        if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_FRAME,
            &ancestor_level))
        {
            /* the error message has already been printed */
            return KEEP_INTERACTING;
        }
    } else if (word_count == 2 && MR_streq(words[1], "clparent")) {
        if (MR_find_clique_entry_mdb(event_info, MR_CLIQUE_ENTRY_PARENT_FRAME,
            &ancestor_level))
        {
            /* the error message has already been printed */
            return KEEP_INTERACTING;
        }
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        ancestor_level = n;
    } else if (word_count == 1) {
        ancestor_level = 0;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    if (ancestor_level == 0 && MR_port_is_entry(event_info->MR_trace_port)) {
        MR_trace_do_noop();
        return KEEP_INTERACTING;
    }

    result = MR_trace_retry(event_info, ancestor_level,
        across_io, assume_all_io_is_tabled, MR_UNTABLED_IO_RETRY_MESSAGE,
        &unsafe_retry, &problem, MR_mdb_in, MR_mdb_out, jumpaddr);
    switch (result) {

    case MR_RETRY_OK_DIRECT:
        cmd->MR_trace_cmd = MR_CMD_GOTO;
        cmd->MR_trace_stop_event = MR_trace_event_number + 1;
        cmd->MR_trace_strict = MR_FALSE;
        cmd->MR_trace_print_level = MR_default_print_level;
        return STOP_INTERACTING;

    case MR_RETRY_OK_FINISH_FIRST:
        cmd->MR_trace_cmd = MR_CMD_FINISH;
        cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
        cmd->MR_trace_strict = MR_TRUE;
        cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;

        /* Arrange to retry the call once it is finished. */
        /* XXX we should use the same options as the original retry */
        MR_insert_command_line_at_head("retry -o");
        return STOP_INTERACTING;

    case MR_RETRY_OK_FAIL_FIRST:
        cmd->MR_trace_cmd = MR_CMD_FAIL;
        cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
        cmd->MR_trace_strict = MR_TRUE;
        cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;

        /* Arrange to retry the call once it is finished. */
        /* XXX we should use the same options as the original retry */
        MR_insert_command_line_at_head("retry -o");
        return STOP_INTERACTING;

    case MR_RETRY_ERROR:
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "%s\n", problem);
        return KEEP_INTERACTING;
    }

    MR_fatal_error("unrecognized retry result");
}