static char *build_ids_from_core_backtrace(const char *dump_dir_name) { char *error = NULL; char *core_backtrace_path = xasprintf("%s/"FILENAME_CORE_BACKTRACE, dump_dir_name); char *json = xmalloc_open_read_close(core_backtrace_path, /*maxsize:*/ NULL); free(core_backtrace_path); if (!json) return NULL; struct sr_core_stacktrace *stacktrace = sr_core_stacktrace_from_json_text(json, &error); free(json); if (!stacktrace) { if (error) { log_info("Failed to parse core backtrace: %s", error); free(error); } return NULL; } struct sr_core_thread *thread = sr_core_stacktrace_find_crash_thread(stacktrace); if (!thread) { log_info("Failed to find crash thread"); sr_core_stacktrace_free(stacktrace); return NULL; } void *build_id_list = NULL; struct strbuf *strbuf = strbuf_new(); for (struct sr_core_frame *frame = thread->frames; frame; frame = frame->next) { if (frame->build_id) build_id_list = g_list_prepend(build_id_list, frame->build_id); } build_id_list = g_list_sort(build_id_list, (GCompareFunc)strcmp); for (GList *iter = build_id_list; iter; iter = g_list_next(iter)) { GList *next = g_list_next(iter); if (next == NULL || 0 != strcmp(iter->data, next->data)) { strbuf = strbuf_append_strf(strbuf, "%s\n", (char *)iter->data); } } g_list_free(build_id_list); sr_core_stacktrace_free(stacktrace); return strbuf_free_nobuf(strbuf); }
static void check_tainted(void) { int tainted = 0; char *buf = xmalloc_open_read_close("/proc/sys/kernel/tainted", NULL); if (buf) { tainted = atoi(buf); if (ENABLE_FEATURE_CLEAN_UP) free(buf); } if (tainted) { printf(" Tainted: %c%c%c\n", tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', tainted & TAINT_FORCED_MODULE ? 'F' : ' ', tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); } else { puts(" Not tainted"); } }
/* returns number of errors */ unsigned abrt_oops_create_dump_dirs(GList *oops_list, const char *dump_location, const char *analyzer, int flags) { const int oops_cnt = g_list_length(oops_list); unsigned countdown = ABRT_OOPS_MAX_DUMPED_COUNT; /* do not report hundreds of oopses */ log_notice("Saving %u oopses as problem dirs", oops_cnt >= countdown ? countdown : oops_cnt); char *cmdline_str = xmalloc_fopen_fgetline_fclose("/proc/cmdline"); char *fips_enabled = xmalloc_fopen_fgetline_fclose("/proc/sys/crypto/fips_enabled"); char *proc_modules = xmalloc_open_read_close("/proc/modules", /*maxsize:*/ NULL); char *suspend_stats = xmalloc_open_read_close("/sys/kernel/debug/suspend_stats", /*maxsize:*/ NULL); time_t t = time(NULL); const char *iso_date = iso_date_string(&t); /* dump should be readable by all if we're run with -x */ uid_t my_euid = (uid_t)-1L; mode_t mode = DEFAULT_DUMP_DIR_MODE | S_IROTH; /* and readable only for the owner otherwise */ if (!(flags & ABRT_OOPS_WORLD_READABLE)) { mode = DEFAULT_DUMP_DIR_MODE; my_euid = geteuid(); } pid_t my_pid = getpid(); unsigned idx = 0; unsigned errors = 0; while (idx < oops_cnt) { char base[sizeof("oops-YYYY-MM-DD-hh:mm:ss-%lu-%lu") + 2 * sizeof(long)*3]; sprintf(base, "oops-%s-%lu-%lu", iso_date, (long)my_pid, (long)idx); char *path = concat_path_file(dump_location, base); struct dump_dir *dd = dd_create(path, /*uid:*/ my_euid, mode); if (dd) { dd_create_basic_files(dd, /*uid:*/ my_euid, NULL); abrt_oops_save_data_in_dump_dir(dd, (char*)g_list_nth_data(oops_list, idx++), proc_modules); dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION); dd_save_text(dd, FILENAME_ANALYZER, "abrt-oops"); dd_save_text(dd, FILENAME_TYPE, "Kerneloops"); if (cmdline_str) dd_save_text(dd, FILENAME_CMDLINE, cmdline_str); if (proc_modules) dd_save_text(dd, "proc_modules", proc_modules); if (fips_enabled && strcmp(fips_enabled, "0") != 0) dd_save_text(dd, "fips_enabled", fips_enabled); if (suspend_stats) dd_save_text(dd, "suspend_stats", suspend_stats); dd_close(dd); notify_new_path(path); } else errors++; free(path); if (--countdown == 0) break; if (dd && (flags & ABRT_OOPS_THROTTLE_CREATION)) if (abrt_oops_signaled_sleep(1) > 0) break; } free(cmdline_str); free(proc_modules); free(fips_enabled); free(suspend_stats); return errors; }