Esempio n. 1
0
static void dup_corebt_init(const struct dump_dir *dd)
{
    if (corebt)
        return; /* already loaded */

    char *corebt_text = load_backtrace(dd);
    if (!corebt_text)
        return; /* no backtrace */

    enum sr_report_type report_type = sr_abrt_type_from_type(type);
    if (report_type == SR_REPORT_INVALID)
    {
        log_notice("Can't load stacktrace because of unsupported type: %s",
                  type);
        return;
    }

    /* sr_stacktrace_parse moves the pointer */
    char *error_message;
    corebt = sr_stacktrace_parse(report_type, corebt_text, &error_message);
    if (!corebt)
    {
        log_notice("Failed to load core stacktrace: %s", error_message);
        free(error_message);
    }

    free(corebt_text);
}
Esempio n. 2
0
static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1,
                                       const char *bt2_text)
{
    struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1);

    if (thread1 == NULL)
    {
        log_notice("New stacktrace has no crash thread, disabling core stacktrace deduplicate");
        dup_corebt_fini();
        return 0;
    }

    int result;
    char *error_message;
    struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_type(type),
                                                    bt2_text, &error_message);
    if (bt2 == NULL)
    {
        log_notice("Failed to parse backtrace, considering it not duplicate: %s", error_message);
        free(error_message);
        return 0;
    }

    struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);

    if (thread2 == NULL)
    {
        log_notice("Failed to get crash thread, considering it not duplicate");
        result = 0;
        goto end;
    }

    int length2 = sr_thread_frame_count(thread2);

    if (length2 <= 0)
    {
        log_notice("Core backtrace has zero frames, considering it not duplicate");
        result = 0;
        goto end;
    }

    float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2);
    log_info("Distance between backtraces: %f", distance);
    result = (distance <= BACKTRACE_DUP_THRESHOLD);

end:
    sr_stacktrace_free(bt2);

    return result;
}
Esempio n. 3
0
enum sr_report_type
sr_abrt_type_from_analyzer(const char *analyzer)
{
    warn("sr_abrt_type_from_analyzer() is deprecated, using sr_abrt_type_from_type() instead");
    return sr_abrt_type_from_type(analyzer);
}
Esempio n. 4
0
struct sr_report *
sr_abrt_report_from_dir(const char *directory,
                        char **error_message)
{
    struct sr_report *report = sr_report_new();

    /* Report type. */
    char *type_contents = file_contents(directory, "type", error_message);
    if (!type_contents)
    {
        sr_report_free(report);
        return NULL;
    }

    report->report_type = sr_abrt_type_from_type(type_contents);
    free(type_contents);

    /* Operating system. */
    report->operating_system = sr_abrt_operating_system_from_dir(
        directory, error_message);

    if (!report->operating_system)
    {
        sr_report_free(report);
        return NULL;
    }

    /* Component name. */
    report->component_name = file_contents(directory, "component", error_message);

    /* RPM packages. */
    report->rpm_packages = sr_abrt_rpm_packages_from_dir(
        directory, error_message);

    if (!report->rpm_packages)
    {
        sr_report_free(report);
        return NULL;
    }

    /* Core stacktrace. */
    if (report->report_type == SR_REPORT_CORE)
    {
        char *core_backtrace_contents = file_contents(directory, "core_backtrace",
                                                      error_message);
        if (!core_backtrace_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        report->stacktrace = (struct sr_stacktrace *)sr_core_stacktrace_from_json_text(
                core_backtrace_contents, error_message);

        free(core_backtrace_contents);
        if (!report->stacktrace)
        {
            sr_report_free(report);
            return NULL;
        }
    }

    /* Python stacktrace. */
    if (report->report_type == SR_REPORT_PYTHON)
    {
        char *backtrace_contents = file_contents(directory, "backtrace",
                                                 error_message);
        if (!backtrace_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        /* Parse the Python stacktrace. */
        struct sr_location location;
        sr_location_init(&location);
        const char *contents_pointer = backtrace_contents;
        report->stacktrace = (struct sr_stacktrace *)sr_python_stacktrace_parse(
            &contents_pointer,
            &location);

        free(backtrace_contents);
        if (!report->stacktrace)
        {
            *error_message = sr_location_to_string(&location);
            sr_report_free(report);
            return NULL;
        }
    }

    /* Kerneloops stacktrace. */
    if (report->report_type == SR_REPORT_KERNELOOPS)
    {
        /* Determine kernel version */
        char *kernel_contents = file_contents(directory, "kernel",
                                              error_message);
        if (!kernel_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        /* Load the Kerneloops stacktrace */
        char *backtrace_contents = file_contents(directory, "backtrace", error_message);
        if (!backtrace_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        /* Parse the Kerneloops stacktrace. */
        struct sr_location location;
        sr_location_init(&location);
        const char *contents_pointer = backtrace_contents;
        struct sr_koops_stacktrace *stacktrace = sr_koops_stacktrace_parse(
            &contents_pointer,
            &location);

        stacktrace->version = kernel_contents;
        report->stacktrace = (struct sr_stacktrace *)stacktrace;

        free(backtrace_contents);
        if (!report->stacktrace)
        {
            *error_message = sr_location_to_string(&location);
            sr_report_free(report);
            return NULL;
        }
    }

    /* Java stacktrace. */
    if (report->report_type == SR_REPORT_JAVA)
    {
        char *backtrace_contents = file_contents(directory, "backtrace", error_message);
        if (!backtrace_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        /* Parse the Java stacktrace. */
        struct sr_location location;
        sr_location_init(&location);
        const char *contents_pointer = backtrace_contents;
        report->stacktrace = (struct sr_stacktrace *)sr_java_stacktrace_parse(
            &contents_pointer,
            &location);

        free(backtrace_contents);
        if (!report->stacktrace)
        {
            *error_message = sr_location_to_string(&location);
            sr_report_free(report);
            return NULL;
        }
    }

    /* Ruby stacktrace. */
    if (report->report_type == SR_REPORT_RUBY)
    {
        char *backtrace_contents = file_contents(directory, "backtrace",
                                                 error_message);
        if (!backtrace_contents)
        {
            sr_report_free(report);
            return NULL;
        }

        /* Parse the Ruby stacktrace. */
        struct sr_location location;
        sr_location_init(&location);
        const char *contents_pointer = backtrace_contents;
        report->stacktrace = (struct sr_stacktrace *)sr_ruby_stacktrace_parse(
            &contents_pointer,
            &location);

        free(backtrace_contents);
        if (!report->stacktrace)
        {
            *error_message = sr_location_to_string(&location);
            sr_report_free(report);
            return NULL;
        }
    }

    return report;
}
Esempio n. 5
0
static int
append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, bool print_item_name, problem_report_settings_t *settings)
{
    const problem_item *backtrace_item = problem_data_get_item_or_NULL(problem_data,
                                                                       FILENAME_BACKTRACE);
    const problem_item *core_stacktrace_item = NULL;
    if (!backtrace_item || !(backtrace_item->flags & CD_FLAG_TXT))
    {
        backtrace_item = NULL;

        core_stacktrace_item = problem_data_get_item_or_NULL(problem_data,
                                                             FILENAME_CORE_BACKTRACE);

        if (!core_stacktrace_item || !(core_stacktrace_item->flags & CD_FLAG_TXT))
            return 0;
    }

    char *truncated = NULL;

    if (core_stacktrace_item || strlen(backtrace_item->content) >= settings->prs_shortbt_max_text_size)
    {
        log_debug("'backtrace' exceeds the text file size, going to append its short version");

        char *error_msg = NULL;
        const char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_TYPE);
        if (!type)
        {
            log_debug("Problem data does not contain '"FILENAME_TYPE"' file");
            return 0;
        }

        /* For CCpp crashes, use the GDB-produced backtrace which should be
         * available by now. sr_abrt_type_from_type returns SR_REPORT_CORE
         * by default for CCpp crashes.
         */
        enum sr_report_type report_type = sr_abrt_type_from_type(type);
        if (backtrace_item && strcmp(type, "CCpp") == 0)
        {
            log_debug("Successfully identified 'CCpp' abrt type");
            report_type = SR_REPORT_GDB;
        }

        const char *content = backtrace_item ? backtrace_item->content : core_stacktrace_item->content;
        struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type, content, &error_msg);

        if (!backtrace)
        {
            log(_("Can't parse backtrace: %s"), error_msg);
            free(error_msg);
            return 0;
        }

        /* normalize */
        struct sr_thread *thread = sr_stacktrace_find_crash_thread(backtrace);
        sr_thread_normalize(thread);

        /* Get optimized thread stack trace for max_frames top most frames */
        truncated = sr_stacktrace_to_short_text(backtrace, settings->prs_shortbt_max_frames);
        sr_stacktrace_free(backtrace);

        if (!truncated)
        {
            log(_("Can't generate stacktrace description (no crash thread?)"));
            return 0;
        }
    }
    else
    {
        log_debug("'backtrace' is small enough to be included as is");
    }

    /* full item content  */
    append_text(result,
                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
                /*content:*/   truncated ? truncated             : backtrace_item->content,
                print_item_name
    );
    free(truncated);
    return 1;
}