Ejemplo n.º 1
0
char *
sr_koops_stacktrace_get_reason(struct sr_koops_stacktrace *stacktrace)
{
    char *func = "<unknown>";
    char *result;

    struct sr_koops_stacktrace *copy = sr_koops_stacktrace_dup(stacktrace);
    sr_normalize_koops_stacktrace(copy);

    if (copy->frames && copy->frames->function_name)
        func = copy->frames->function_name;

    if (copy->frames && copy->frames->module_name)
    {
        result = sr_asprintf("Kernel oops in %s [%s]", func,
                copy->frames->module_name);
    }
    else
        result = sr_asprintf("Kernel oops in %s", func);

    sr_koops_stacktrace_free(copy);

    return result;
}
Ejemplo n.º 2
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);

    /* save crash_function into dumpdir */
    char *error_message = NULL;
    struct sr_stacktrace *stacktrace = sr_stacktrace_parse(SR_REPORT_KERNELOOPS,
                                                           (const char *)second_line, &error_message);

    if (stacktrace)
    {
        sr_normalize_koops_stacktrace((struct sr_koops_stacktrace *)stacktrace);
        /* stacktrace is the same as thread, there is no need to check return value */
        struct sr_thread *thread = sr_stacktrace_find_crash_thread(stacktrace);
        struct sr_koops_frame *frame = (struct sr_koops_frame *)sr_thread_frames(thread);
        if (frame && frame->function_name)
            dd_save_text(dd, FILENAME_CRASH_FUNCTION, frame->function_name);

        sr_stacktrace_free(stacktrace);
    }
    else
    {
        error_msg("Can't parse stacktrace: %s", error_message);
        free(error_message);
    }

    /* 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);
}