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