MR_Next
MR_trace_cmd_goto(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned n;
    const char  *generator_name;

    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 == 2 && MR_trace_is_natural_number(words[1], &n)) {
        generator_name = NULL;
        if (MR_trace_event_number < n
            || !MR_cur_generator_is_named(generator_name))
        {
            cmd->MR_trace_cmd = MR_CMD_GOTO;
            cmd->MR_trace_stop_event = n;
            cmd->MR_trace_stop_generator = generator_name;
            return STOP_INTERACTING;
        } else {
            fflush(MR_mdb_out);
            // XXX This message is misleading.
            fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
        }
#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
    } else if (word_count == 3 && MR_trace_is_natural_number(words[1], &n)) {
        generator_name = words[2];
        if (MR_trace_event_number < n
            || !MR_cur_generator_is_named(generator_name))
        {
            cmd->MR_trace_cmd = MR_CMD_GOTO;
            cmd->MR_trace_stop_event = n;
            // We don't ever deallocate the memory allocated here,
            // but this memory leak leaks only negligible amounts of memory.

            cmd->MR_trace_stop_generator = strdup(generator_name);
            return STOP_INTERACTING;
        } else {
            fflush(MR_mdb_out);
            // XXX This message is misleading.
            fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
        }
#endif
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_maxdepth(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned newdepth;

    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 == 2 &&
        MR_trace_is_natural_number(words[1], &newdepth))
    {
        cmd->MR_trace_cmd = MR_CMD_MAX_DEPTH;
        cmd->MR_trace_stop_depth = newdepth;
        return STOP_INTERACTING;
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
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;
}
MR_Next
MR_trace_cmd_untrust(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned i;

    if (word_count == 2 && MR_trace_is_natural_number(words[1], &i)) {
        if (!MR_decl_remove_trusted(i)) {
            fprintf(MR_mdb_err, "mdb: no such trusted object\n");
        }
    } else {
        MR_trace_usage_cur_cmd();
    }
    return KEEP_INTERACTING;
}
Beispiel #5
0
MR_Next
MR_trace_cmd_down(char **words, int word_count, MR_TraceCmdInfo *cmd,
                  MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned n;
    MR_bool     detailed;

    detailed = MR_FALSE;
    if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
        ; /* the usage message has already been printed */
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        MR_trace_set_level_and_report(MR_trace_current_level() - n, detailed,
                                      MR_print_optionals);
    } else if (word_count == 1) {
        MR_trace_set_level_and_report(MR_trace_current_level() - 1, detailed,
                                      MR_print_optionals);
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Beispiel #6
0
MR_Next
MR_trace_cmd_level(char **words, int word_count, MR_TraceCmdInfo *cmd,
                   MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned n;
    MR_bool     detailed;
    MR_Level    selected_level;

    detailed = MR_FALSE;
    if (! MR_trace_options_detailed(&detailed, &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,
                                     &selected_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,
                                     &selected_level))
        {
            /* the error message has already been printed */
            return KEEP_INTERACTING;
        }
    } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
        selected_level = n;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    MR_trace_set_level_and_report(selected_level, detailed,
                                  MR_print_optionals);
    return KEEP_INTERACTING;
}
Beispiel #7
0
void
MR_trace_expand_aliases(char ***words, int *word_max, int *word_count)
{
    const char  *alias_key;
    char        **alias_words;
    int         alias_word_count;
    int         alias_copy_start;
    int         i;
    MR_Unsigned n;

    if (*word_count == 0) {
        alias_key = "EMPTY";
        alias_copy_start = 0;
    } else if (MR_trace_is_natural_number(*words[0], &n)) {
        alias_key = "NUMBER";
        alias_copy_start = 0;
    } else {
        alias_key = *words[0];
        alias_copy_start = 1;
    }

    if (MR_trace_lookup_alias(alias_key, &alias_words, &alias_word_count)) {
        MR_ensure_big_enough(*word_count + alias_word_count, *word, char *,
            MR_INIT_WORD_COUNT);

        // Move the original words (except the alias key) up.
        for (i = *word_count - 1; i >= alias_copy_start; i--) {
            (*words)[i + alias_word_count - alias_copy_start] = (*words)[i];
        }

        // Move the alias body to the words array.
        for (i = 0; i < alias_word_count; i++) {
            (*words)[i] = alias_words[i];
        }

        *word_count += alias_word_count - alias_copy_start;
    }
static MR_bool
MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
    MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
    MR_DeclSearchMode *search_mode, MR_bool *search_mode_was_set,
    MR_bool *search_mode_requires_trace_counts,
    char **pass_trace_counts_file, char **fail_trace_counts_file,
    MR_bool *new_session, MR_bool *reset_kb, MR_bool *testing,
    MR_bool *debug, char ***words, int *word_count)
{
    int c;

    MR_optind = 0;
    while ((c = MR_getopt_long(*word_count, *words, "ad:f:n:p:rRs:tz",
        MR_trace_dd_opts, NULL)) != EOF)
    {
        switch (c) {

            case 'a':
                *assume_all_io_is_tabled = MR_TRUE;
                break;

            case 'd':
                if (! MR_trace_is_natural_number(MR_optarg, default_depth)) {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 'f':
                *fail_trace_counts_file = MR_copy_string(MR_optarg);
                break;

            case 'n':
                if (! MR_trace_is_natural_number(MR_optarg, num_nodes)) {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 'p':
                *pass_trace_counts_file = MR_copy_string(MR_optarg);
                break;

            case 'r':
                *new_session = MR_FALSE;
                break;

            case 'R':
                *reset_kb = MR_TRUE;
                break;

            case 's':
                if (MR_trace_is_valid_search_mode_string(MR_optarg,
                    search_mode, search_mode_requires_trace_counts))
                {
                    *search_mode_was_set = MR_TRUE;
                } else {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 't':
                *testing = MR_TRUE;
                break;

            case 'z':
                *debug = MR_TRUE;
                break;

            default:
                MR_trace_usage_cur_cmd();
                return MR_FALSE;
        }
    }

    *words = *words + MR_optind - 1;
    *word_count = *word_count - MR_optind + 1;
    return MR_TRUE;
}
MR_Next
MR_trace_cmd_trust(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_ProcSpec         spec;
    MR_MatchesInfo      matches;

    if (word_count == 2) {
        spec.MR_proc_module = NULL;
        spec.MR_proc_name   = NULL;
        spec.MR_proc_arity  = -1;
        spec.MR_proc_mode   = -1;
        spec.MR_proc_prefix = (MR_ProcPrefix) -1;

        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);

        /* First see if the argument is a module name */
        spec.MR_proc_module = words[1];
        matches = MR_search_for_matching_procedures(&spec);
        if (matches.match_proc_next > 0) {
            MR_decl_add_trusted_module(words[1]);
            fprintf(MR_mdb_out, "Trusting module %s\n", words[1]);
        } else if (MR_parse_proc_spec(words[1], &spec)) {
            /* Check to see if the argument is a pred/func */
            matches = MR_search_for_matching_procedures(&spec);
            MR_filter_user_preds(&matches);
            if (matches.match_proc_next == 0) {
                fprintf(MR_mdb_err,
                    "mdb: there is no such module, predicate or function.\n");
            } else if (matches.match_proc_next == 1) {
                MR_decl_add_trusted_pred_or_func(matches.match_procs[0]);
                fprintf(MR_mdb_out, "Trusting ");
                MR_print_pred_id_and_nl(MR_mdb_out, matches.match_procs[0]);
            } else {
                MR_Unsigned i;
                char        buf[80];
                char        *line2;

                fprintf(MR_mdb_out, "Ambiguous predicate or function"
                    " specification. The matches are:\n");
                for (i = 0; i < matches.match_proc_next; i++) {
                    fprintf(MR_mdb_out, "%" MR_INTEGER_LENGTH_MODIFIER "u: ",
                        i);
                    MR_print_pred_id_and_nl(MR_mdb_out,
                        matches.match_procs[i]);
                }
                sprintf(buf, "\nWhich predicate or function "
                    "do you want to trust (0-%" MR_INTEGER_LENGTH_MODIFIER
                    "u or *)? ",
                    matches.match_proc_next - 1);
                line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
                if (line2 == NULL) {
                    /* This means the user input EOF. */
                    fprintf(MR_mdb_out, "none of them\n");
                } else if (MR_streq(line2, "*")) {
                    for (i = 0; i < matches.match_proc_next; i++) {
                        MR_decl_add_trusted_pred_or_func(
                            matches.match_procs[i]);

                        fprintf(MR_mdb_out, "Trusting ");
                        MR_print_pred_id_and_nl(MR_mdb_out,
                            matches.match_procs[i]);
                    }
                    MR_free(line2);
                } else if(MR_trace_is_natural_number(line2, &i)) {
                    if (0 <= i && i < matches.match_proc_next) {
                        MR_decl_add_trusted_pred_or_func(
                            matches.match_procs[i]);

                        fprintf(MR_mdb_out, "Trusting ");
                        MR_print_pred_id_and_nl(MR_mdb_out,
                            matches.match_procs[i]);
                    } else {
                        fprintf(MR_mdb_out, "no such match\n");
                    }
                    MR_free(line2);
                } else {
                    fprintf(MR_mdb_out, "none of them\n");
                    MR_free(line2);
                }
            }
        }
    } else if (word_count == 3 &&
        ((MR_streq(words[1], "std") && MR_streq(words[2], "lib"))
        || (MR_streq(words[1], "standard") && MR_streq(words[2], "library"))))
    {
        MR_decl_trust_standard_library();
        fprintf(MR_mdb_out, "Trusting the Mercury standard library\n");
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
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_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;
}
Beispiel #12
0
MR_Next
MR_trace_cmd_stack(char **words, int word_count, MR_TraceCmdInfo *cmd,
                   MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_bool                 print_all;
    MR_bool                 detailed;
    MR_FrameLimit           frame_limit;
    MR_SpecLineLimit        clique_line_limit;
    MR_SpecLineLimit        line_limit;
    MR_SpecLineLimit        spec_line_limit;
    const MR_LabelLayout    *layout;
    MR_Word                 *saved_regs;
    const char              *msg;

    detailed = MR_FALSE;
    print_all = MR_FALSE;
    frame_limit = 0;
    clique_line_limit = 10;
    line_limit = 100;
    if (! MR_trace_options_stack_trace(&print_all, &detailed,
                                       &line_limit, &clique_line_limit, &frame_limit, &words, &word_count))
    {
        /* the usage message has already been printed */
        return KEEP_INTERACTING;
    } else if (word_count == 1) {
        line_limit = MR_stack_default_line_limit;
    } else if (word_count == 2 &&
               MR_trace_is_natural_number(words[1], &spec_line_limit))
    {
        line_limit = spec_line_limit;
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    layout = event_info->MR_event_sll;
    saved_regs = event_info->MR_saved_regs;

#ifdef  MR_DEBUG_STACK_DUMP_CLIQUE
    MR_trace_init_modules();
    fprintf(MR_mdb_out, "OLD STACK DUMP:\n");
    msg = MR_dump_stack_from_layout(MR_mdb_out, layout,
                                    MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
                                    detailed, MR_context_position != MR_CONTEXT_NOWHERE,
                                    frame_limit, line_limit,
                                    &MR_dump_stack_record_print);

    if (msg != NULL) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "%s.\n", msg);
    }

    fprintf(MR_mdb_out, "\nNEW STACK DUMP:\n");
#endif
    msg = MR_dump_stack_from_layout_clique(MR_mdb_out, layout,
                                           MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
                                           detailed, MR_context_position != MR_CONTEXT_NOWHERE,
                                           !print_all, clique_line_limit, frame_limit, line_limit,
                                           &MR_dump_stack_record_print);

    if (msg != NULL) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "%s.\n", msg);
    }

    return KEEP_INTERACTING;
}
Beispiel #13
0
MR_Next
MR_trace_cmd_browse(char **words, int word_count, MR_TraceCmdInfo *cmd,
                    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_BrowseFormat     format;
    MR_bool             xml;
    MR_IoActionNum      action;
    MR_GoalBrowser      goal_browser;
    MR_Browser          browser;
    const char          *problem;

    if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
        ; /* the usage message has already been printed */
    } else {
        if (xml) {
            goal_browser = MR_trace_browse_goal_xml;
            browser = MR_trace_browse_xml;
        } else {
            goal_browser = MR_trace_browse_goal_internal;
            browser = MR_trace_browse_internal;
        }

        if (word_count == 1) {
            problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
                                               MR_BROWSE_CALLER_BROWSE, format);

            if (problem != NULL) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err, "mdb: %s.\n", problem);
            }
        } else if (word_count == 2) {
            if (MR_streq(words[1], "goal")) {
                problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
                                                   MR_BROWSE_CALLER_BROWSE, format);
            } else if (MR_streq(words[1], "exception")) {
                problem = MR_trace_browse_exception(event_info, browser,
                                                    MR_BROWSE_CALLER_BROWSE, format);
            } else if (MR_streq(words[1], "proc_body")) {
                problem = MR_trace_browse_proc_body(event_info, browser,
                                                    MR_BROWSE_CALLER_BROWSE, format);
            } else {
                problem = MR_trace_parse_browse_one(MR_mdb_out, MR_FALSE,
                                                    words[1], browser, MR_BROWSE_CALLER_BROWSE, format,
                                                    MR_TRUE);
            }

            if (problem != NULL) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err, "mdb: %s.\n", problem);
            }
        } else if (word_count == 3 &&
                   (MR_streq(words[1], "io") || MR_streq(words[1], "action"))
                   && MR_trace_is_natural_number(words[2], &action))
        {
            problem = MR_trace_browse_action(MR_mdb_out, action, goal_browser,
                                             MR_BROWSE_CALLER_BROWSE, format);

            if (problem != NULL) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err, "mdb: %s.\n", problem);
            }
        } else {
            MR_trace_usage_cur_cmd();
        }
    }

    return KEEP_INTERACTING;
}
Beispiel #14
0
MR_Next
MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd,
                   MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_BrowseFormat     format;
    MR_bool             xml;
    const char          *problem;
    MR_Unsigned         action;
    MR_Unsigned         lo_action;
    MR_Unsigned         hi_action;
    static MR_bool      have_next_io_action = MR_FALSE;
    static MR_Unsigned  next_io_action = 0;

    if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
        ; /* the usage message has already been printed */
    } else if (xml) {
        /* the --xml option is not valid for print */
        MR_trace_usage_cur_cmd();
    } else if (word_count == 1) {
        problem = MR_trace_browse_one_goal(MR_mdb_out,
                                           MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format);

        if (problem != NULL) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err, "mdb: %s.\n", problem);
        }
    } else if (word_count == 2) {
        if (MR_streq(words[1], "*")) {
            problem = MR_trace_browse_all(MR_mdb_out,
                                          MR_trace_browse_internal, format);
        } else if (MR_streq(words[1], "goal")) {
            problem = MR_trace_browse_one_goal(MR_mdb_out,
                                               MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format);
        } else if (MR_streq(words[1], "exception")) {
            problem = MR_trace_browse_exception(event_info,
                                                MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
        } else if (MR_streq(words[1], "proc_body")) {
            problem = MR_trace_browse_proc_body(event_info,
                                                MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
        } else if ((MR_streq(words[1], "io") || MR_streq(words[1], "action")))
        {
            MR_Unsigned num_printed_actions;

            if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err,
                        "mdb: I/O tabling has not yet started.\n");
                return KEEP_INTERACTING;
            }

            if (MR_io_tabling_counter_hwm == 0) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err,
                        "mdb: There are no tabled I/O actions yet.\n");
                return KEEP_INTERACTING;
            }

            if (have_next_io_action && (!
                                        (MR_io_tabling_start <= next_io_action
                                         && next_io_action < MR_io_tabling_counter_hwm)))
            {
                have_next_io_action = MR_FALSE;
            }

            if (have_next_io_action) {
                lo_action = next_io_action;
            } else {
                lo_action = MR_io_tabling_start;
            }

            hi_action = lo_action + MR_MAX_NUM_IO_ACTIONS_TO_PRINT;
            if (hi_action >= MR_io_tabling_counter_hwm) {
                hi_action = MR_io_tabling_counter_hwm - 1;
            }

            num_printed_actions = hi_action - lo_action + 1;
            if (num_printed_actions <= 0) {
                fprintf(MR_mdb_out, "There are no I/O actions to print\n");
                have_next_io_action = MR_FALSE;
            } else {
                for (action = lo_action; action <= hi_action; action++) {
                    fprintf(MR_mdb_out,
                            "action %" MR_INTEGER_LENGTH_MODIFIER "u: ", action);
                    problem = MR_trace_browse_action(MR_mdb_out, action,
                                                     MR_trace_browse_goal_internal,
                                                     MR_BROWSE_CALLER_PRINT, format);

                    if (problem != NULL) {
                        fflush(MR_mdb_out);
                        fprintf(MR_mdb_err, "mdb: %s.\n", problem);
                        return KEEP_INTERACTING;
                    }
                }

                if (hi_action == MR_io_tabling_counter_hwm - 1) {
                    fprintf(MR_mdb_out,
                            "there are no more actions (yet)\n");
                } else {
                    fprintf(MR_mdb_out,
                            "there are more actions, up to action "
                            "%" MR_INTEGER_LENGTH_MODIFIER "u\n",
                            MR_io_tabling_counter_hwm - 1);
                }

                next_io_action = hi_action + 1;
                have_next_io_action = MR_TRUE;
            }
        } else {
            problem = MR_trace_parse_browse_one(MR_mdb_out, MR_TRUE, words[1],
                                                MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format,
                                                MR_FALSE);
        }

        if (problem != NULL) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err, "mdb: %s.\n", problem);
        }
    } else if (word_count == 3 &&
               (MR_streq(words[1], "io") || MR_streq(words[1], "action")))
    {
        if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err,
                    "mdb: I/O tabling has not yet started.\n");
            return KEEP_INTERACTING;
        }

        if (MR_io_tabling_counter_hwm == 0) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err,
                    "mdb: There are no tabled I/O actions yet.\n");
            return KEEP_INTERACTING;
        }

        if (MR_streq(words[2], "limits")) {
            fprintf(MR_mdb_out,
                    "I/O tabling has recorded actions "
                    "%" MR_INTEGER_LENGTH_MODIFIER "u to "
                    "%" MR_INTEGER_LENGTH_MODIFIER "u.\n",
                    MR_io_tabling_start, MR_io_tabling_counter_hwm - 1);
            fflush(MR_mdb_out);
        } else if (MR_trace_is_natural_number(words[2], &action)) {
            problem = MR_trace_browse_action(MR_mdb_out, action,
                                             MR_trace_browse_goal_internal,
                                             MR_BROWSE_CALLER_PRINT, format);

            if (problem != NULL) {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err, "mdb: %s.\n", problem);
                have_next_io_action = MR_FALSE;
            }

            next_io_action = action + 1;
            have_next_io_action = MR_TRUE;
        } else if (MR_trace_is_natural_number_pair(words[2],
                   &lo_action, &hi_action))
        {
            if (lo_action >= hi_action) {
                /* swap lo_action and hi_action */
                MR_Unsigned tmp;

                tmp = lo_action;
                lo_action = hi_action;
                hi_action = tmp;
            }

            if (! (MR_io_tabling_start <= lo_action
                    && hi_action < MR_io_tabling_counter_hwm))
            {
                fflush(MR_mdb_out);
                fprintf(MR_mdb_err,
                        "I/O tabling has only recorded actions "
                        "%" MR_INTEGER_LENGTH_MODIFIER "u to "
                        "%" MR_INTEGER_LENGTH_MODIFIER "u.\n",
                        MR_io_tabling_start, MR_io_tabling_counter_hwm - 1);
                have_next_io_action = MR_FALSE;
                return KEEP_INTERACTING;
            }

            for (action = lo_action; action <= hi_action; action++) {
                fprintf(MR_mdb_out,
                        "action %" MR_INTEGER_LENGTH_MODIFIER "u: ", action);
                problem = MR_trace_browse_action(MR_mdb_out, action,
                                                 MR_trace_browse_goal_internal,
                                                 MR_BROWSE_CALLER_PRINT, format);

                if (problem != NULL) {
                    fflush(MR_mdb_out);
                    fprintf(MR_mdb_err, "mdb: %s.\n", problem);
                    return KEEP_INTERACTING;
                }
            }

            next_io_action = hi_action + 1;
            have_next_io_action = MR_TRUE;
        } else {
            MR_trace_usage_cur_cmd();
        }
    } else {
        MR_trace_usage_cur_cmd();
    }

    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");
}