struct sr_core_stacktrace * sr_core_stacktrace_from_gdb(const char *gdb_output, const char *core_file, const char *exe_file, char **error_msg) { /* I'm not going to rewrite it now since the function is not being used. */ assert(error_msg); /* Initialize error_msg to 'no error'. */ *error_msg = NULL; struct core_handle *ch = open_coredump(core_file, exe_file, error_msg); if (*error_msg) return NULL; struct sr_gdb_stacktrace *gdb_stacktrace; struct sr_location location; sr_location_init(&location); gdb_stacktrace = sr_gdb_stacktrace_parse(&gdb_output, &location); if (!gdb_stacktrace) { *error_msg = sr_location_to_string(&location); core_handle_free(ch); return NULL; } struct sr_core_stacktrace *core_stacktrace = sr_core_stacktrace_new(); for (struct sr_gdb_thread *gdb_thread = gdb_stacktrace->threads; gdb_thread; gdb_thread = gdb_thread->next) { struct sr_core_thread *core_thread = sr_core_thread_new(); for (struct sr_gdb_frame *gdb_frame = gdb_thread->frames; gdb_frame; gdb_frame = gdb_frame->next) { if (gdb_frame->signal_handler_called) continue; struct sr_core_frame *core_frame = resolve_frame(ch->dwfl, gdb_frame->address, false); core_thread->frames = sr_core_frame_append(core_thread->frames, core_frame); } if (sr_gdb_stacktrace_find_crash_thread(gdb_stacktrace) == gdb_thread) { core_stacktrace->crash_thread = core_thread; } core_stacktrace->threads = sr_core_thread_append( core_stacktrace->threads, core_thread); } core_stacktrace->signal = get_signal_number(ch->eh, core_file); core_stacktrace->executable = realpath(exe_file, NULL); core_handle_free(ch); sr_gdb_stacktrace_free(gdb_stacktrace); return core_stacktrace; }
struct sr_core_stacktrace * sr_parse_coredump_maps(const char *core_file, const char *exe_file, const char *maps_file, char **error_msg) { struct sr_core_stacktrace *stacktrace = NULL; /* Initialize error_msg to 'no error'. */ if (error_msg) *error_msg = NULL; struct core_handle *ch = open_coredump(core_file, exe_file, maps_file, error_msg); if (!ch) goto fail; if (dwfl_core_file_attach(ch->dwfl, ch->eh) < 0) { set_error_dwfl("dwfl_core_file_attach"); goto fail; } stacktrace = sr_core_stacktrace_new(); if (!stacktrace) { set_error("Failed to initialize stacktrace memory"); goto fail; } struct thread_callback_arg thread_arg = { .stacktrace = stacktrace, .error_msg = NULL }; int ret = dwfl_getthreads(ch->dwfl, unwind_thread, &thread_arg); if (ret != 0) { if (ret == -1) set_error_dwfl("dwfl_getthreads"); else if (ret == DWARF_CB_ABORT) { set_error("%s", thread_arg.error_msg); free(thread_arg.error_msg); } else set_error("Unknown error in dwfl_getthreads"); sr_core_stacktrace_free(stacktrace); stacktrace = NULL; goto fail; } stacktrace->executable = sr_strdup(exe_file); stacktrace->signal = get_signal_number(ch->eh, core_file); /* FIXME: is this the best we can do? */ stacktrace->crash_thread = stacktrace->threads; fail: core_handle_free(ch); return stacktrace; }