Exemplo n.º 1
0
void
MR_trace_report(FILE *fp)
{
    if (MR_trace_event_number > 0) {
        // This means that the executable was compiled with tracing,
        // which implies that the user wants trace info on abort.

        if (MR_trace_report_msg != NULL) {
            fprintf(fp, "%s\n", MR_trace_report_msg);
        }

        if (MR_standardize_event_details) {
            fprintf(fp, "Last trace event was event #E%ld.\n",
                (long) MR_standardize_event_num(MR_trace_event_number));
        } else {
            fprintf(fp, "Last trace event was event #%ld.\n",
                (long) MR_trace_event_number);
        }

#ifdef  MR_TRACE_HISTOGRAM
        {
            FILE    *hfp;
            char    errbuf[MR_STRERROR_BUF_SIZE];

            hfp = fopen(MR_TRACE_HISTOGRAM_FILENAME, "w");
            if (hfp != NULL) {
                MR_trace_print_histogram(hfp, "All-inclusive",
                    MR_trace_histogram_all, MR_trace_histogram_hwm);
                if (fclose(hfp) == 0) {
                    fprintf(fp, "Event histogram put into file `%s'.\n",
                        MR_TRACE_HISTOGRAM_FILENAME);
                } else {
                    fprintf(fp, "Cannot put event histogram into `%s': %s."
                        MR_TRACE_HISTOGRAM_FILENAME,
                        MR_strerror(errno, errbuf, sizeof(errbuf)));
                }
            } else {
                fprintf(fp, "Cannot open `%s': %s.\n"
                    MR_TRACE_HISTOGRAM_FILENAME,
                    MR_strerror(errno, errbuf, sizeof(errbuf)));
            }
        }
#endif  // MR_TRACE_HISTOGRAM
    }
}
Exemplo n.º 2
0
void
MR_checked_atexit(void (*func)(void))
{
    char errbuf[MR_STRERROR_BUF_SIZE];

    errno = 0;
    if (atexit(func) != 0) {
        fprintf(stderr, "Mercury runtime: error in call to atexit: %s\n",
            MR_strerror(errno, errbuf, sizeof(errbuf)));
        exit(EXIT_FAILURE);
    }
}
Exemplo n.º 3
0
void
MR_checked_fclose(FILE *file, const char *filename)
{
    char errbuf[MR_STRERROR_BUF_SIZE];

    errno = 0;
    if (fclose(file) != 0) {
        fprintf(stderr, "Mercury runtime: error closing file `%s': %s\n",
            filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
        exit(EXIT_FAILURE);
    }
}
Exemplo n.º 4
0
FILE *
MR_checked_fopen(const char *filename, const char *message, const char *mode)
{
    FILE *file;
    char errbuf[MR_STRERROR_BUF_SIZE];

    errno = 0;
    file = fopen(filename, mode);
    if (file == NULL) {
        fprintf(stderr, "Mercury runtime: couldn't %s file `%s': %s\n",
            message, filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
        exit(EXIT_FAILURE);
    }
    return file;
}
Exemplo n.º 5
0
void
MR_trace_record_label_exec_counts(void *dummy)
{
    FILE        *fp;
    char        *name;
    unsigned    name_len;
    MR_bool     summarize;
    MR_bool     keep;
    char        *slash;
    const char  *program_name;
    char        errbuf[MR_STRERROR_BUF_SIZE];

    program_name = MR_copy_string(MR_progname);
    slash = strrchr(program_name, '/');
    if (slash != NULL) {
        program_name = slash + 1;
    }

    summarize = MR_FALSE;
    keep = MR_FALSE;
    if (MR_trace_count_summary_file != NULL) {
        if (MR_FILE_EXISTS(MR_trace_count_summary_file)) {
            int     i;

            // 30 bytes must be enough for the dot, the value of i, and '\0'.
            name_len = strlen(MR_trace_count_summary_file) + 30;
            name = MR_malloc(name_len);

            fp = NULL;
            // Search for a suffix that doesn't exist yet.
            for (i = 1; i <= MR_trace_count_summary_max; i++) {
                snprintf(name, name_len, "%s.%d",
                    MR_trace_count_summary_file, i);
                if (! MR_FILE_EXISTS(name)) {
                    // File doesn't exist, commit to this one.
                    if (i == MR_trace_count_summary_max) {
                        summarize = MR_TRUE;
                    }

                    break;
                }
            }
        } else {
            // The summary file doesn't yet exist, create it.
            name = MR_copy_string(MR_trace_count_summary_file);
        }
    } else if (MR_trace_counts_file) {
        name = MR_copy_string(MR_trace_counts_file);
        keep = MR_TRUE;
    } else {
        char    *s;

        // If no trace counts file name is provided, then we generate
        // a file name.

        // 100 bytes must be enough for the process id, dots and '\0'.
        name_len = strlen(MERCURY_TRACE_COUNTS_PREFIX) + strlen(program_name)
            + 100;
        name = MR_malloc(name_len);
        snprintf(name, name_len, ".%s.%s.%d", MERCURY_TRACE_COUNTS_PREFIX,
            program_name, getpid());

        // Make sure name is an acceptable filename.
        for (s = name; *s != '\0'; s++) {
            if (*s == '/') {
                *s = '_';
            }
        }
    }

    fp = fopen(name, "w");
    if (fp != NULL) {
        unsigned    num_written;

        num_written = MR_trace_write_label_exec_counts(fp,
            program_name, MR_coverage_test_enabled);
        (void) fclose(fp);

        if (num_written == 0 && !keep) {
            // We did not write out any trace counts, so there is nothing
            // to gather.
            (void) unlink(name);
            summarize = MR_FALSE;
        }
    } else {
        fprintf(stderr, "%s: %s\n", name,
            MR_strerror(errno, errbuf, sizeof(errbuf)));
        // You can't summarize a file list if you can't create
        // one of its files.
        summarize = MR_FALSE;
    }

    free(name);

    if (summarize) {
        char        *cmd;
        unsigned    cmd_len;
        int         summary_status;
        int         mv_status;
        int         unlink_status;
        int         i;
        const char  *old_options;

        // 30 bytes must be enough for the dot, the value of i, and space.
        name_len = strlen(MR_trace_count_summary_file) + 30;
        name = MR_malloc(name_len);

        cmd_len = strlen(MR_trace_count_summary_cmd) + 4;
        cmd_len += strlen(MR_trace_count_summary_file)
            + strlen(TEMP_SUFFIX) + 1;
        cmd_len += (MR_trace_count_summary_max + 1) * name_len;
        cmd_len += 100;

        cmd = MR_malloc(cmd_len);

        strcpy(cmd, MR_trace_count_summary_cmd);
        strcat(cmd, " -o ");
        strcat(cmd, MR_trace_count_summary_file);
        strcat(cmd, TEMP_SUFFIX);
        strcat(cmd, " ");
        strcat(cmd, MR_trace_count_summary_file);

        for (i = 1; i <= MR_trace_count_summary_max; i++) {
            snprintf(name, name_len, "%s.%d", MR_trace_count_summary_file, i);
            strcat(cmd, " ");
            strcat(cmd, name);
        }

        strcat(cmd, " > /dev/null 2>&1");

        old_options = getenv("MERCURY_OPTIONS");
        if (old_options != NULL) {
            (void) MR_setenv("MERCURY_OPTIONS", "", MR_TRUE);
            summary_status = system(cmd);
            (void) MR_setenv("MERCURY_OPTIONS", old_options, MR_TRUE);
        } else {
            summary_status = system(cmd);
        }

        if (summary_status == 0) {
            strcpy(cmd, "mv ");
            strcat(cmd, MR_trace_count_summary_file);
            strcat(cmd, TEMP_SUFFIX);
            strcat(cmd, " ");
            strcat(cmd, MR_trace_count_summary_file);
            mv_status = system(cmd);

            if (mv_status == 0) {
                // Delete all files whose data is now in the summary file.
                for (i = 1; i <= MR_trace_count_summary_max; i++) {
                    snprintf(name, name_len, "%s.%d",
                        MR_trace_count_summary_file, i);
                    unlink_status = unlink(name);
                    if (unlink_status != 0) {
                        MR_fatal_error(
                            "couldn't create summary of trace data");
                    }
                }
            } else {
                MR_fatal_error("couldn't create summary of trace data");
            }
        } else {
            MR_fatal_error("couldn't create summary of trace data");
        }

        free(name);
        free(cmd);
    }
}