Ejemplo 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);
}
Ejemplo 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;
}
Ejemplo n.º 3
0
int koops_hash_str_ext(char result[SHA1_RESULT_LEN*2 + 1], const char *oops_buf, int frame_count, int duphash_flags)
{
    char *hash_str = NULL, *error = NULL;
    int bad = 0;

    struct sr_stacktrace *stacktrace = sr_stacktrace_parse(SR_REPORT_KERNELOOPS,
                                                           oops_buf, &error);
    if (!stacktrace)
    {
        log_debug("Failed to parse koops: %s", error);
        free(error);
        bad = 1;
        goto end;
    }

    struct sr_thread *thread = sr_stacktrace_find_crash_thread(stacktrace);
    if (!thread)
    {
        log_debug("Failed to find crash thread");
        bad = 1;
        goto end;
    }

    if (g_verbose >= 3)
    {
        hash_str = sr_thread_get_duphash(thread, frame_count, NULL,
                                         duphash_flags|SR_DUPHASH_NOHASH);
        if (hash_str)
            log("Generating duphash: '%s'", hash_str);
        else
            log("Nothing useful for duphash");


        free(hash_str);
    }

    hash_str = sr_thread_get_duphash(thread, frame_count, NULL, duphash_flags);
    if (hash_str)
    {
        strncpy(result, hash_str, SHA1_RESULT_LEN*2);
        result[SHA1_RESULT_LEN*2] = '\0';
        free(hash_str);
    }
    else
        bad = 1;

end:
    sr_stacktrace_free(stacktrace);
    return bad;
}
Ejemplo n.º 4
0
void abrt_oops_save_data_in_dump_dir(struct dump_dir *dd, char *oops, const char *proc_modules)
{
    char *first_line = oops;
    char *second_line = (char*)strchr(first_line, '\n'); /* never NULL */
    *second_line++ = '\0';

    if (first_line[0])
        dd_save_text(dd, FILENAME_KERNEL, first_line);
    dd_save_text(dd, FILENAME_BACKTRACE, second_line);

    /* check if trace doesn't have line: 'Your BIOS is broken' */
    if (strstr(second_line, "Your BIOS is broken"))
        dd_save_text(dd, FILENAME_NOT_REPORTABLE,
                _("A kernel problem occurred because of broken BIOS. "
                  "Unfortunately, such problems are not fixable by kernel maintainers."));
    /* check if trace doesn't have line: 'Your hardware is unsupported' */
    else if (strstr(second_line, "Your hardware is unsupported"))
        dd_save_text(dd, FILENAME_NOT_REPORTABLE,
                _("A kernel problem occurred, but your hardware is unsupported, "
                  "therefore kernel maintainers are unable to fix this problem."));
    else
    {
        char *tainted_short = kernel_tainted_short(second_line);
        if (tainted_short)
        {
            log_notice("Kernel is tainted '%s'", tainted_short);
            dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short);

            char *tnt_long = kernel_tainted_long(tainted_short);
            dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long);
            free(tnt_long);

            struct strbuf *reason = strbuf_new();
            const char *fmt = _("A kernel problem occurred, but your kernel has been "
                    "tainted (flags:%s). Kernel maintainers are unable to "
                    "diagnose tainted reports.");
            strbuf_append_strf(reason, fmt, tainted_short);

            char *modlist = !proc_modules ? NULL : abrt_oops_list_of_tainted_modules(proc_modules);
            if (modlist)
            {
                strbuf_append_strf(reason, _(" Tainted modules: %s."), modlist);
                free(modlist);
            }

            dd_save_text(dd, FILENAME_NOT_REPORTABLE, reason->buf);
            strbuf_free(reason);
            free(tainted_short);
        }
    }

    // TODO: add "Kernel oops: " prefix, so that all oopses have recognizable FILENAME_REASON?
    // kernel oops 1st line may look quite puzzling otherwise...
    char *reason_pretty = NULL;
    char *error = NULL;
    struct sr_stacktrace *trace = sr_stacktrace_parse(SR_REPORT_KERNELOOPS, second_line, &error);
    if (trace)
    {
        reason_pretty = sr_stacktrace_get_reason(trace);
        sr_stacktrace_free(trace);
    }
    else
        free(error);

    if (reason_pretty)
    {
        dd_save_text(dd, FILENAME_REASON, reason_pretty);
        free(reason_pretty);
    }
    else
        dd_save_text(dd, FILENAME_REASON, second_line);
}
Ejemplo n.º 5
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_analyzer(analyzer),
                                                    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;
    }

    /* This is an ugly workaround for https://github.com/abrt/btparser/issues/6 */
    /*
    int length1 = sr_core_thread_get_frame_count(thread1);

    if (length1 <= 2 || length2 <= 2)
    {
        log_notice("Backtraces too short, falling back on full comparison");
        result = (sr_core_thread_cmp(thread1, thread2) == 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;
}
Ejemplo n.º 6
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;
}