Example #1
0
MR_Next
MR_trace_cmd_hold(char **words, int word_count, MR_TraceCmdInfo *cmd,
                  MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    char        *event_var_name;
    char        *held_var_name;
    MR_TypeInfo type_info;
    MR_Word     value;
    const char  *ignored_name;
    const char  *problem;
    MR_bool     bad_subterm;

    if (word_count == 2) {
        event_var_name = words[1];
        held_var_name = words[1];
    } else if (word_count == 3) {
        event_var_name = words[1];
        held_var_name = words[2];
    } else {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    if (strpbrk(held_var_name, "^/") != NULL) {
        /* Don't allow path separators in variable names. */
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    if (held_var_name[0] == '$') {
        /* Ignore any unneeded initial $ signs. */
        held_var_name = &held_var_name[1];
    }

    problem = MR_trace_parse_lookup_var_path(event_var_name, &type_info,
              &value, &bad_subterm);
    if (problem != NULL) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: %s%s.\n",
                (bad_subterm? "there is no path " : ""), problem);
        return KEEP_INTERACTING;
    }

    if (! MR_add_hold_var(held_var_name, type_info, value)) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: there is already a held variable $%s\n",
                held_var_name);
    }

    return KEEP_INTERACTING;
}
Example #2
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;
}
Example #3
0
MR_Next
MR_trace_cmd_continue(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    cmd->MR_trace_strict = MR_FALSE;
    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) {
        cmd->MR_trace_cmd = MR_CMD_TO_END;
        if (! cmd->MR_trace_print_level_specified) {
            // The user did not specify the print level;
            // select the intelligent default.

            if (cmd->MR_trace_strict) {
                cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
            } else {
                cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
            }
        }
        return STOP_INTERACTING;
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Example #4
0
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;
}
Example #5
0
static MR_bool
MR_trace_options_movement_cmd(MR_TraceCmdInfo *cmd,
    char ***words, int *word_count)
{
    int c;

#ifdef  MR_TRACE_CHECK_INTEGRITY
  #define   MR_TRACE_MOVEMENT_OPTS  "NSains"
#else
  #define   MR_TRACE_MOVEMENT_OPTS  "NSans"
#endif

    MR_optind = 0;
    while ((c = MR_getopt_long(*word_count, *words, MR_TRACE_MOVEMENT_OPTS,
        MR_trace_movement_cmd_opts, NULL)) != EOF)
    {
        switch (c) {

            case 'N':
                cmd->MR_trace_strict = MR_FALSE;
                break;

            case 'S':
                cmd->MR_trace_strict = MR_TRUE;
                break;

            case 'a':
                cmd->MR_trace_print_level_specified = MR_TRUE;
                cmd->MR_trace_print_level = MR_PRINT_LEVEL_ALL;
                break;

            case 'n':
                cmd->MR_trace_print_level_specified = MR_TRUE;
                cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
                break;

            case 's':
                cmd->MR_trace_print_level_specified = MR_TRUE;
                cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
                break;

#ifdef  MR_TRACE_CHECK_INTEGRITY
            case 'i':
                cmd->MR_trace_check_integrity = MR_TRUE;
                break;
#endif

            default:
                MR_trace_usage_cur_cmd();
                return MR_FALSE;
        }
    }

    *words = *words + MR_optind - 1;
    *word_count = *word_count - MR_optind + 1;
    return MR_TRUE;
}
Example #6
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;
}
MR_Next
MR_trace_cmd_trusted(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    if (word_count == 1) {
        MR_decl_print_all_trusted(MR_mdb_out, MR_FALSE);
    } else {
        MR_trace_usage_cur_cmd();
    }
    return KEEP_INTERACTING;
}
Example #8
0
MR_Next
MR_trace_cmd_diff(char **words, int word_count, MR_TraceCmdInfo *cmd,
                  MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_Unsigned start;
    MR_Unsigned max;
    char        *name1;
    char        *name2;
    MR_TypeInfo type_info1;
    MR_TypeInfo type_info2;
    MR_Word     value1;
    MR_Word     value2;
    MR_Word     univ1;
    MR_Word     univ2;
    const char  *problem1;
    const char  *problem2;
    MR_bool     bad_subterm1;
    MR_bool     bad_subterm2;

    start = 0;
    max = 20;
    if (! MR_trace_options_diff(&start, &max, &words, &word_count)) {
        /* the usage message has already been printed */
        return KEEP_INTERACTING;
    } else if (word_count != 3) {
        MR_trace_usage_cur_cmd();
        return KEEP_INTERACTING;
    }

    name1 = words[1];
    name2 = words[2];
    problem1 = MR_trace_parse_lookup_var_path(name1, &type_info1, &value1,
               &bad_subterm1);
    problem2 = MR_trace_parse_lookup_var_path(name2, &type_info2, &value2,
               &bad_subterm2);
    if (problem1 != NULL) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: %s%s.\n",
                (bad_subterm1? "arg1: there is no path " : ""), problem1);
        return KEEP_INTERACTING;
    }
    if (problem2 != NULL) {
        fflush(MR_mdb_out);
        fprintf(MR_mdb_err, "mdb: %s%s.\n",
                (bad_subterm2? "arg2: there is no path " : ""), problem2);
        return KEEP_INTERACTING;
    }

    MR_TRACE_CALL_MERCURY(
        MR_new_univ_on_hp(univ1, type_info1, value1);
        MR_new_univ_on_hp(univ2, type_info2, value2);
        ML_report_diffs(start, max, univ1, univ2);
    );
Example #9
0
MR_Next
MR_trace_cmd_current(char **words, int word_count, MR_TraceCmdInfo *cmd,
                     MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    if (word_count == 1) {
        MR_trace_event_print_internal_report(event_info);
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Example #10
0
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;
}
Example #11
0
MR_Next
MR_trace_cmd_held_vars(char **words, int word_count, MR_TraceCmdInfo *cmd,
                       MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    if (word_count == 1) {
        MR_trace_list_held_vars(MR_mdb_out);
    } else {
        MR_trace_usage_cur_cmd();
    }

    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;
}
Example #13
0
MR_Next
MR_trace_cmd_vars(char **words, int word_count, MR_TraceCmdInfo *cmd,
                  MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    if (word_count == 1) {
        const char  *problem;

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

    return KEEP_INTERACTING;
}
Example #14
0
MR_Next
MR_trace_cmd_user(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) {
        cmd->MR_trace_cmd = MR_CMD_USER;
        return STOP_INTERACTING;
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Example #15
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;
}
Example #16
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;
}
static MR_bool
MR_trace_options_retry(MR_RetryAcrossIo *across_io,
    MR_bool *assume_all_io_is_tabled, char ***words, int *word_count)
{
    int c;

    MR_optind = 0;
    while ((c = MR_getopt_long(*word_count, *words, "afio",
        MR_trace_retry_opts, NULL)) != EOF)
    {
        switch (c) {

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

            case 'f':
                *across_io = MR_RETRY_IO_FORCE;
                break;

            case 'i':
                *across_io = MR_RETRY_IO_INTERACTIVE;
                break;

            case 'o':
                *across_io = MR_RETRY_IO_ONLY_IF_SAFE;
                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;
}
Example #18
0
MR_Next
MR_trace_cmd_view(char **words, int word_count, MR_TraceCmdInfo *cmd,
                  MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    const char      *window_cmd = NULL;
    const char      *server_cmd = NULL;
    const char      *server_name = NULL;
    MR_Unsigned     timeout = 8;    /* seconds */
    MR_bool         force = MR_FALSE;
    MR_bool         verbose = MR_FALSE;
    MR_bool         split = MR_FALSE;
    MR_bool         close_window = MR_FALSE;
    const char      *msg;

    if (! MR_trace_options_view(&window_cmd, &server_cmd, &server_name,
                                &timeout, &force, &verbose, &split, &close_window,
                                &words, &word_count))
    {
        ; /* the usage message has already been printed */
    } else if (word_count != 1) {
        MR_trace_usage_cur_cmd();
    } else if (close_window) {
        MR_trace_maybe_close_source_window(verbose);
    } else {
        msg = MR_trace_new_source_window(window_cmd, server_cmd, server_name,
                                         timeout, force, verbose, split);
        if (msg != NULL) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err, "mdb: %s.\n", msg);
        }

        MR_trace_maybe_sync_source_window(event_info, verbose);
    }

    return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_table_io(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    if (word_count == 1) {
        if (! MR_io_tabling_allowed) {
            fprintf(MR_mdb_err,
                "This executable wasn't prepared for I/O tabling.\n");
            return KEEP_INTERACTING;
        }

        if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
            fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
            fprintf(MR_mdb_out, "I/O tabling has started.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
            fprintf(MR_mdb_out, "I/O tabling has stopped.\n");
        } else {
            MR_fatal_error("I/O tabling in impossible phase.\n");
        }
    } else if (word_count == 2 &&
        (MR_streq(words[1], "start") || MR_streq(words[1], "begin")))
    {
        if (! MR_io_tabling_allowed) {
            fprintf(MR_mdb_err,
                "This executable wasn't prepared for I/O tabling.\n");
            return KEEP_INTERACTING;
        }

        if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
            MR_io_tabling_phase = MR_IO_TABLING_DURING;
            MR_io_tabling_start = MR_io_tabling_counter;
            MR_io_tabling_end = MR_IO_ACTION_MAX;
            MR_io_tabling_start_event_num = event_info->MR_event_number;
#ifdef  MR_DEBUG_RETRY
            MR_io_tabling_debug = MR_TRUE;
#endif
            fprintf(MR_mdb_out, "I/O tabling started.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
            fprintf(MR_mdb_out, "I/O tabling has already started.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
            fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
        } else {
            MR_fatal_error("I/O tabling in impossible phase.\n");
        }
    } else if (word_count == 2 &&
        (MR_streq(words[1], "stop") || MR_streq(words[1], "end")))
    {
        if (! MR_io_tabling_allowed) {
            fprintf(MR_mdb_err,
                "This executable wasn't prepared for I/O tabling.\n");
            return KEEP_INTERACTING;
        }

        if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
            fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
            MR_io_tabling_phase = MR_IO_TABLING_AFTER;
            MR_io_tabling_end = MR_io_tabling_counter_hwm;
            MR_io_tabling_stop_event_num = event_info->MR_event_number;
            fprintf(MR_mdb_out, "I/O tabling stopped.\n");
        } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
            fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
        } else {
            MR_fatal_error("I/O tabling in impossible phase.\n");
        }
    } else if (word_count == 2 && MR_streq(words[1], "stats")) {
        if (! MR_io_tabling_allowed) {
            fprintf(MR_mdb_err,
                "This executable wasn't prepared for I/O tabling.\n");
            return KEEP_INTERACTING;
        }

        fprintf(MR_mdb_out, "phase = %d\n", MR_io_tabling_phase);
        MR_print_unsigned_var(MR_mdb_out, "counter", MR_io_tabling_counter);
        MR_print_unsigned_var(MR_mdb_out, "hwm", MR_io_tabling_counter_hwm);
        MR_print_unsigned_var(MR_mdb_out, "start", MR_io_tabling_start);
        MR_print_unsigned_var(MR_mdb_out, "end", MR_io_tabling_end);
    } else if (word_count == 2 && MR_streq(words[1], "allow")) {
        /*
        ** The "table_io allow" command allows the programmer to give
        ** the command "table_io start" even in grades in which there
        ** is no guarantee that all I/O primitives are tabled. It is
        ** for developers only, because if it is used on programs in
        ** which some but not all I/O primitives are tabled, the
        ** results of turning on I/O tabling can be weird.
        */

        MR_io_tabling_allowed = MR_TRUE;
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
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;
}
Example #21
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;
}
Example #22
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;
}
Example #23
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;
}
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_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");
}
Example #26
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_dd(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_DeclSearchMode   search_mode;
    MR_bool             search_mode_was_set = MR_FALSE;
    MR_bool             new_session = MR_TRUE;
    MR_bool             reset_kb = MR_FALSE;
    MR_bool             search_mode_requires_trace_counts = MR_FALSE;
    char                *pass_trace_counts_file;
    char                *fail_trace_counts_file;
    MR_String           problem;
    MR_bool             testing = MR_FALSE;
    const char          *filename;
    MR_DeclMode         decl_mode;

    MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
    MR_edt_default_depth_limit = MR_TRACE_DECL_INITIAL_DEPTH;
    search_mode = MR_trace_get_default_search_mode();
    pass_trace_counts_file = MR_dice_pass_trace_counts_file;
    fail_trace_counts_file = MR_dice_fail_trace_counts_file;
    MR_trace_decl_debug_debugger_mode = MR_FALSE;

    if (! MR_trace_options_dd(&MR_trace_decl_assume_all_io_is_tabled,
        &MR_edt_default_depth_limit, &MR_edt_desired_nodes_in_subtree,
        &search_mode, &search_mode_was_set,
        &search_mode_requires_trace_counts,
        &pass_trace_counts_file, &fail_trace_counts_file, &new_session,
        &reset_kb, &testing, &MR_trace_decl_debug_debugger_mode, &words,
        &word_count))
    {
        ; /* the usage message has already been printed */
    } else if (word_count <= 2) {
        if (word_count == 2 && MR_trace_decl_debug_debugger_mode) {
            decl_mode = MR_DECL_DUMP;
            filename = (const char *) words[1];
        } else {
            decl_mode = MR_DECL_NODUMP;
            filename = (const char *) NULL;
        }

        if (MR_trace_have_unhid_events) {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err,
                "mdb: dd doesn't work after `unhide_events on'.\n");
            return KEEP_INTERACTING;
        }

        if (search_mode_requires_trace_counts && (
            pass_trace_counts_file == NULL || fail_trace_counts_file == NULL))
        {
            fflush(MR_mdb_out);
            fprintf(MR_mdb_err,
                "mdb: you need to supply passing and failing trace count "
                "files\nbefore using the specified search mode.\n");
            return KEEP_INTERACTING;
        }

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

        MR_trace_decl_set_testing_flag(testing);

        if (new_session) {
            MR_trace_decl_session_init();
        }

        if (search_mode_was_set || new_session) {
            MR_trace_decl_set_fallback_search_mode(search_mode);
        }

        if (reset_kb) {
            MR_trace_decl_reset_knowledge_base();
        }

        if (MR_trace_start_decl_debug(decl_mode, filename, new_session, cmd,
            event_info, jumpaddr))
        {
            return STOP_INTERACTING;
        }
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Example #28
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;
}