char * sr_abrt_get_core_stacktrace_from_core_hook(pid_t thread_id, const char *executable, int signum, char **error_message) { struct sr_core_stacktrace *core_stacktrace; core_stacktrace = sr_core_stacktrace_from_core_hook(thread_id, executable, signum, error_message); if (!core_stacktrace) return false; fulfill_missing_values(core_stacktrace); char *json = sr_core_stacktrace_to_json(core_stacktrace); sr_core_stacktrace_free(core_stacktrace); // Add newline to the end of core stacktrace file to make text // editors happy. json = sr_realloc(json, strlen(json) + 2); strcat(json, "\n"); return json; ; }
static bool create_core_stacktrace(const char *directory, const char *gdb_output, bool hash_fingerprints, char **error_message) { char *executable_contents = file_contents(directory, "executable", error_message); if (!executable_contents) return NULL; char *coredump_filename = sr_build_path(directory, "coredump", NULL); struct sr_core_stacktrace *core_stacktrace; if (gdb_output) core_stacktrace = sr_core_stacktrace_from_gdb(gdb_output, coredump_filename, executable_contents, error_message); else core_stacktrace = sr_parse_coredump(coredump_filename, executable_contents, error_message); free(executable_contents); free(coredump_filename); if (!core_stacktrace) return false; fulfill_missing_values(core_stacktrace); #if 0 sr_core_fingerprint_generate(core_stacktrace, error_message); if (hash_fingerprints) sr_core_fingerprint_hash(core_stacktrace); #endif char *json = sr_core_stacktrace_to_json(core_stacktrace); // Add newline to the end of core stacktrace file to make text // editors happy. json = sr_realloc(json, strlen(json) + 2); strcat(json, "\n"); char *core_backtrace_filename = sr_build_path(directory, "core_backtrace", NULL); bool success = sr_string_to_file(core_backtrace_filename, json, error_message); free(core_backtrace_filename); free(json); sr_core_stacktrace_free(core_stacktrace); return success; }
struct sr_koops_stacktrace * sr_koops_stacktrace_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace")) return NULL; struct sr_koops_stacktrace *result = sr_koops_stacktrace_new(); /* Kernel version. */ if (!JSON_READ_STRING(root, "version", &result->version)) goto fail; /* Raw oops text. */ if (!JSON_READ_STRING(root, "raw_oops", &result->raw_oops)) goto fail; /* Kernel taint flags. */ struct sr_json_value *taint_flags = json_element(root, "taint_flags"); if (taint_flags) { if (!JSON_CHECK_TYPE(taint_flags, SR_JSON_ARRAY, "taint_flags")) goto fail; struct sr_json_value *flag_json; FOR_JSON_ARRAY(taint_flags, flag_json) { if (!JSON_CHECK_TYPE(flag_json, SR_JSON_STRING, "taint flag")) goto fail; for (struct sr_taint_flag *f = sr_flags; f->name; f++) { if (0 == strcmp(f->name, flag_json->u.string.ptr)) { *(bool *)((void *)result + f->member_offset) = true; break; } } /* XXX should we do something if nothing is set? */ } } /* Modules. */ struct sr_json_value *modules = json_element(root, "modules"); if (modules) { if (!JSON_CHECK_TYPE(modules, SR_JSON_ARRAY, "modules")) goto fail; unsigned i = 0; size_t allocated = 128; result->modules = sr_malloc_array(allocated, sizeof(char*)); struct sr_json_value *mod_json; FOR_JSON_ARRAY(modules, mod_json) { if (!JSON_CHECK_TYPE(mod_json, SR_JSON_STRING, "module")) goto fail; /* need to keep the last element for NULL terminator */ if (i+1 == allocated) { allocated *= 2; result->modules = sr_realloc(result->modules, allocated); } result->modules[i] = sr_strdup(mod_json->u.string.ptr); i++; } result->modules[i] = NULL; } /* Frames. */ struct sr_json_value *frames = json_element(root, "frames"); if (frames) { if (!JSON_CHECK_TYPE(frames, SR_JSON_ARRAY, "frames")) goto fail; struct sr_json_value *frame_json; FOR_JSON_ARRAY(frames, frame_json) { struct sr_koops_frame *frame = sr_koops_frame_from_json(frame_json, error_message); if (!frame) goto fail; result->frames = sr_koops_frame_append(result->frames, frame); } } return result; fail: sr_koops_stacktrace_free(result); return NULL; }