diff --git a/SOURCES/satyr-0.13-abrt-refactorize-unwinding-from-core-hook.patch b/SOURCES/satyr-0.13-abrt-refactorize-unwinding-from-core-hook.patch new file mode 100644 index 0000000..c1821fd --- /dev/null +++ b/SOURCES/satyr-0.13-abrt-refactorize-unwinding-from-core-hook.patch @@ -0,0 +1,99 @@ +From 89e0a7d0a195605585b80157ce23be1fb03f04a2 Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Wed, 13 May 2015 10:45:32 +0200 +Subject: [PATCH] abrt: refactorize unwinding from core hook + +ABRT needs to save files from its core hook with O_EXCL and with right +mode and owner and there might be more constraints ABRT needs to +respect in future. + +This patch breaks granularity of the abrt functions to allow ABRT to save the +core backtrace data in the way it need by providing a function returning +the data instead of directly saving the data to a file. + +Signed-off-by: Jakub Filak +--- + include/abrt.h | 6 ++++++ + lib/abrt.c | 29 ++++++++++++++++++++++------- + 2 files changed, 28 insertions(+), 7 deletions(-) + +diff --git a/include/abrt.h b/include/abrt.h +index 5116446..ca0748c 100644 +--- a/include/abrt.h ++++ b/include/abrt.h +@@ -44,6 +44,12 @@ sr_abrt_create_core_stacktrace_from_gdb(const char *directory, + bool hash_fingerprints, + char **error_message); + ++char * ++sr_abrt_get_core_stacktrace_from_core_hook(pid_t thread_id, ++ const char *executable, ++ int signum, ++ char **error_message); ++ + bool + sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, + pid_t thread_id, +diff --git a/lib/abrt.c b/lib/abrt.c +index 86e9082..4599e2c 100644 +--- a/lib/abrt.c ++++ b/lib/abrt.c +@@ -162,12 +162,11 @@ sr_abrt_create_core_stacktrace(const char *directory, + error_message); + } + +-bool +-sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, +- pid_t thread_id, +- const char *executable, +- int signum, +- char **error_message) ++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; +@@ -180,12 +179,29 @@ sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, + 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; ++; ++} ++ ++bool ++sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, ++ pid_t thread_id, ++ const char *executable, ++ int signum, ++ char **error_message) ++{ ++ char *json = sr_abrt_get_core_stacktrace_from_core_hook(thread_id, ++ executable, ++ signum, ++ error_message); ++ + char *core_backtrace_filename = sr_build_path(directory, "core_backtrace", NULL); + bool success = sr_string_to_file(core_backtrace_filename, + json, +@@ -193,7 +209,6 @@ sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, + + free(core_backtrace_filename); + free(json); +- sr_core_stacktrace_free(core_stacktrace); + return success; + } + +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-core_unwind-fix-the-missing-frame-build_id-and-file.patch b/SOURCES/satyr-0.13-core_unwind-fix-the-missing-frame-build_id-and-file.patch new file mode 100644 index 0000000..92b4fc5 --- /dev/null +++ b/SOURCES/satyr-0.13-core_unwind-fix-the-missing-frame-build_id-and-file.patch @@ -0,0 +1,49 @@ +From d34232858880672a9e6b88ff5ebd966969aabb9f Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Mon, 7 Sep 2015 08:08:16 +0200 +Subject: [PATCH] core_unwind: fix the missing frame build_id and file_name + +The documentation of dwfl_module_build_id() says: + + This returns 0 when the module's main ELF file has not yet been loaded + and its build ID bits were not reported. To ensure the ID is always + returned when determinable, call dwfl_module_getelf first. + + /usr/include/elfutils/libdwfl.h + +ABRT upstream commit 88c6b3683a129c0e369071204b29fbca94772d3b verifies +this patch. + +Discovered by Richard Marko +Resolved by Mark Wielaard + +Related: #1210599 + +Signed-off-by: Jakub Filak +--- + lib/core_unwind.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/lib/core_unwind.c b/lib/core_unwind.c +index cf9973a..c30f9db 100644 +--- a/lib/core_unwind.c ++++ b/lib/core_unwind.c +@@ -278,9 +278,14 @@ resolve_frame(Dwfl *dwfl, Dwarf_Addr ip, bool minus_one) + int ret; + const unsigned char *build_id_bits; + const char *filename, *funcname; +- GElf_Addr bid_addr; ++ GElf_Addr bias, bid_addr; + Dwarf_Addr start; + ++ /* Initialize the module's main Elf for dwfl_module_build_id and dwfl_module_info */ ++ /* No need to deallocate the variable 'bias' and the return value.*/ ++ if (NULL == dwfl_module_getelf(mod, &bias)) ++ warn("The module's main Elf was not found"); ++ + ret = dwfl_module_build_id(mod, &build_id_bits, &bid_addr); + if (ret > 0) + { +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-debug-unwinding-from-core-hook-using-satyr-binary.patch b/SOURCES/satyr-0.13-debug-unwinding-from-core-hook-using-satyr-binary.patch new file mode 100644 index 0000000..21bd205 --- /dev/null +++ b/SOURCES/satyr-0.13-debug-unwinding-from-core-hook-using-satyr-binary.patch @@ -0,0 +1,133 @@ +From 455c47f1f18858c439ff0a0b833ce93c9f79045f Mon Sep 17 00:00:00 2001 +From: Martin Milata +Date: Mon, 24 Nov 2014 14:38:06 +0100 +Subject: [PATCH 4/5] debug unwinding from core hook using satyr binary + +Write "|/usr/bin/satyr debug unwind-from-hook %e %i %s" to +/proc/sys/kernel/core_pattern in order to use this. Before kernel 3.18 +the %i flag is not available - you can use %p for single-thread +processes. + +Related to abrt/abrt#829. + +Signed-off-by: Martin Milata +--- + satyr.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 81 insertions(+) + +diff --git a/satyr.c b/satyr.c +index 7bdaa45..6e1ed28 100644 +--- a/satyr.c ++++ b/satyr.c +@@ -20,6 +20,8 @@ + #include "gdb/stacktrace.h" + #include "gdb/thread.h" + #include "gdb/frame.h" ++#include "core/unwind.h" ++#include "core/stacktrace.h" + #include "utils.h" + #include "location.h" + #include "strbuf.h" +@@ -37,6 +39,7 @@ + #include + #include + #include ++#include + + static char *g_program_name; + +@@ -275,6 +278,82 @@ debug_duphash(int argc, char **argv) + } + + static void ++debug_unwind_from_hook(int argc, char **argv) ++{ ++ if (argc != 3) ++ { ++ fprintf(stderr, "Wrong number of arguments.\n"); ++ fprintf(stderr, "Usage: satyr debug unwind-from-hook " ++ " \n"); ++ exit(1); ++ } ++ ++ char *executable = argv[0]; ++ char *end; ++ unsigned long tid = strtoul(argv[1], &end, 10); ++ if (*end != '\0') ++ { ++ fprintf(stderr, "Wrong tid\n"); ++ exit(1); ++ } ++ ++ unsigned long signum = strtoul(argv[2], &end, 10); ++ if (*end != '\0') ++ { ++ fprintf(stderr, "Wrong signal number\n"); ++ exit(1); ++ } ++ ++ char *error_message = NULL; ++ struct sr_core_stacktrace *core_stacktrace; ++ ++ core_stacktrace = sr_core_stacktrace_from_core_hook(tid, executable, signum, ++ &error_message); ++ if (!core_stacktrace) ++ { ++ fprintf(stderr, "Unwind failed: %s\n", error_message); ++ exit(1); ++ } ++ ++ 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"); ++ ++ time_t t = time(NULL); ++ struct tm *tm = localtime(&t); ++ char core_backtrace_filename[256]; ++ ++ if (tm == NULL) ++ { ++ perror("localtime"); ++ exit(1); ++ } ++ ++ if (strftime(core_backtrace_filename, sizeof(core_backtrace_filename), ++ "/tmp/satyr-core-stacktrace-%F-%T.json", tm) == 0) ++ { ++ fprintf(stderr, "stftime failed\n"); ++ exit(1); ++ } ++ ++ ++ bool success = sr_string_to_file(core_backtrace_filename, ++ json, ++ &error_message); ++ ++ if (!success) ++ { ++ fprintf(stderr, "Failed to write stacktrace: %s\n", error_message); ++ exit(1); ++ } ++ ++ free(json); ++ sr_core_stacktrace_free(core_stacktrace); ++} ++ ++static void + debug(int argc, char **argv) + { + /* Debug command requires a subcommand. */ +@@ -288,6 +367,8 @@ debug(int argc, char **argv) + debug_normalize(argc - 1, argv + 1); + else if (0 == strcmp(argv[0], "duphash")) + debug_duphash(argc - 1, argv + 1); ++ else if (0 == strcmp(argv[0], "unwind-from-hook")) ++ debug_unwind_from_hook(argc - 1, argv + 1); + else + { + fprintf(stderr, "Unknown debug subcommand.\n"); +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-disable-hook-unwind-on-kernels-w-o-PTRACE_SEIZE.patch b/SOURCES/satyr-0.13-disable-hook-unwind-on-kernels-w-o-PTRACE_SEIZE.patch new file mode 100644 index 0000000..c181365 --- /dev/null +++ b/SOURCES/satyr-0.13-disable-hook-unwind-on-kernels-w-o-PTRACE_SEIZE.patch @@ -0,0 +1,73 @@ +From c1497bdb2a1deaa467fa75a80b1fb993a7d500f5 Mon Sep 17 00:00:00 2001 +From: Martin Milata +Date: Mon, 8 Dec 2014 15:37:17 +0100 +Subject: [PATCH 5/5] Disable hook unwind on kernels w/o PTRACE_SEIZE + +Related to abrt/abrt#829. + +Signed-off-by: Martin Milata +--- + lib/core_unwind.c | 7 ++++--- + lib/core_unwind_elfutils.c | 6 ++++++ + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/lib/core_unwind.c b/lib/core_unwind.c +index 8599f0f..cf9973a 100644 +--- a/lib/core_unwind.c ++++ b/lib/core_unwind.c +@@ -25,6 +25,7 @@ + #include + #include + #include /* struct elf_prstatus */ ++#include /* PTRACE_SEIZE */ + + #include "utils.h" + #include "core/unwind.h" +@@ -52,19 +53,19 @@ sr_parse_coredump(const char *coredump_filename, + + #endif /* !defined WITH_LIBDWFL && !defined WITH_LIBUNWIND */ + +-#if !defined WITH_LIBDWFL ++#if (!defined WITH_LIBDWFL || !defined PTRACE_SEIZE) + + struct sr_core_stacktrace * + sr_core_stacktrace_from_core_hook(pid_t thread_id, + const char *executable_filename, + int signum, +- char **error_message); ++ char **error_message) + { + *error_message = sr_asprintf("satyr is built without live process unwind support"); + return NULL; + } + +-#endif /* !defined WITH_LIBDWFL */ ++#endif /* !defined WITH_LIBDWFL || !defined PTRACE_SEIZE */ + + /* FIXME: is there another way to pass the executable name to the find_elf + * callback? */ +diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c +index eb366cd..1482dba 100644 +--- a/lib/core_unwind_elfutils.c ++++ b/lib/core_unwind_elfutils.c +@@ -212,6 +212,10 @@ fail: + return stacktrace; + } + ++/* If PTRACE_SEIZE is not defined (kernel < 3.4), stub function from ++ * core_unwind.c is used. */ ++#ifdef PTRACE_SEIZE ++ + struct sr_core_stacktrace * + sr_core_stacktrace_from_core_hook(pid_t tid, + const char *executable, +@@ -344,4 +348,6 @@ fail: + return stacktrace; + } + ++#endif /* PTRACE_SEIZE */ ++ + #endif /* WITH_LIBDWFL */ +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-fulfill-missing-values-in-core-frames.patch b/SOURCES/satyr-0.13-fulfill-missing-values-in-core-frames.patch new file mode 100644 index 0000000..83ed2b6 --- /dev/null +++ b/SOURCES/satyr-0.13-fulfill-missing-values-in-core-frames.patch @@ -0,0 +1,67 @@ +From 90f464eb0c1ee4f5c23cb34ec6d199ae648625fe Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Fri, 16 May 2014 13:50:22 +0200 +Subject: [PATCH 1/5] Fulfill missing values in core/frames + +File name of __kernel_vsyscall function frame cannot be resolved but we +known that the function comes from kernel. + +The frame often appears in backtraces of sleep. + +Signed-off-by: Jakub Filak +--- + lib/abrt.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/lib/abrt.c b/lib/abrt.c +index 39bc45d..ed33800 100644 +--- a/lib/abrt.c ++++ b/lib/abrt.c +@@ -24,6 +24,8 @@ + #include "operating_system.h" + #include "core/unwind.h" + #include "core/stacktrace.h" ++#include "core/thread.h" ++#include "core/frame.h" + #include "core/fingerprint.h" + #include "python/stacktrace.h" + #include "koops/stacktrace.h" +@@ -62,6 +64,26 @@ sr_abrt_print_report_from_dir(const char *directory, + return true; + } + ++static void ++fulfill_missing_values(struct sr_core_stacktrace *core_stacktrace) ++{ ++ struct sr_core_thread *thread = core_stacktrace->threads; ++ while (thread) ++ { ++ struct sr_core_frame *frame = thread->frames; ++ while (frame) ++ { ++ if (!frame->file_name && frame->function_name ++ && strcmp("__kernel_vsyscall", frame->function_name) == 0) ++ { ++ frame->file_name = sr_strdup("kernel"); ++ } ++ frame = frame->next; ++ } ++ thread = thread->next; ++ } ++} ++ + static bool + create_core_stacktrace(const char *directory, const char *gdb_output, + bool hash_fingerprints, char **error_message) +@@ -87,6 +109,8 @@ create_core_stacktrace(const char *directory, const char *gdb_output, + if (!core_stacktrace) + return false; + ++ fulfill_missing_values(core_stacktrace); ++ + #if 0 + sr_core_fingerprint_generate(core_stacktrace, + error_message); +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-support-unwinding-from-core-hook.patch b/SOURCES/satyr-0.13-support-unwinding-from-core-hook.patch new file mode 100644 index 0000000..56a3060 --- /dev/null +++ b/SOURCES/satyr-0.13-support-unwinding-from-core-hook.patch @@ -0,0 +1,308 @@ +From 91cdbeb45d11cfd1dd62afe50f80a7c5d4342f5b Mon Sep 17 00:00:00 2001 +From: Martin Milata +Date: Mon, 24 Nov 2014 14:36:14 +0100 +Subject: [SATYR PATCH] unwind: support unwinding from core hook + +In-memory unwinding of dying processes, related to abrt/abrt#gh829. The +implementation mostly mirrors code in src/stack.c of elfutils repo +(jankratochvil/corepattern branch). + +Related to abrt/abrt#829. + +Signed-off-by: Martin Milata +--- + include/abrt.h | 8 +++ + include/core/unwind.h | 18 ++++++ + lib/abrt.c | 35 ++++++++++++ + lib/core_unwind.c | 14 +++++ + lib/core_unwind_elfutils.c | 136 +++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 211 insertions(+) + +diff --git a/include/abrt.h b/include/abrt.h +index 0a8f5ac..5116446 100644 +--- a/include/abrt.h ++++ b/include/abrt.h +@@ -26,6 +26,7 @@ extern "C" { + + #include "report_type.h" + #include ++#include + + bool + sr_abrt_print_report_from_dir(const char *directory, +@@ -43,6 +44,13 @@ sr_abrt_create_core_stacktrace_from_gdb(const char *directory, + bool hash_fingerprints, + char **error_message); + ++bool ++sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, ++ pid_t thread_id, ++ const char *executable, ++ int signum, ++ char **error_message); ++ + struct sr_rpm_package * + sr_abrt_parse_dso_list(const char *text); + +diff --git a/include/core/unwind.h b/include/core/unwind.h +index 8ab9d52..b128c76 100644 +--- a/include/core/unwind.h ++++ b/include/core/unwind.h +@@ -24,6 +24,8 @@ + extern "C" { + #endif + ++#include ++ + struct sr_core_stacktrace; + struct sr_gdb_stacktrace; + +@@ -38,6 +40,22 @@ sr_core_stacktrace_from_gdb(const char *gdb_output, + const char *executable_filename, + char **error_message); + ++/* This function can be used to unwind stack of live ("dying") process, invoked ++ * from the core dump hook (/proc/sys/kernel/core_pattern). ++ * ++ * Beware: ++ * ++ * - It can only unwind one thread of the process, the thread that caused the ++ * terminating signal to be sent. You must supply that thread's tid. ++ * - The function calls close() on stdin, meaning that in the core handler you ++ * cannot access the core image after calling this function. ++ */ ++struct sr_core_stacktrace * ++sr_core_stacktrace_from_core_hook(pid_t thread_id, ++ const char *executable_filename, ++ int signum, ++ char **error_message); ++ + #ifdef __cplusplus + } + #endif +diff --git a/lib/abrt.c b/lib/abrt.c +index 39bc45d..585fdfb 100644 +--- a/lib/abrt.c ++++ b/lib/abrt.c +@@ -138,6 +138,41 @@ sr_abrt_create_core_stacktrace(const char *directory, + error_message); + } + ++bool ++sr_abrt_create_core_stacktrace_from_core_hook(const char *directory, ++ 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); ++ ++ // 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_rpm_package * + sr_abrt_parse_dso_list(const char *text) + { +diff --git a/lib/core_unwind.c b/lib/core_unwind.c +index 8b7cc22..7ea66da 100644 +--- a/lib/core_unwind.c ++++ b/lib/core_unwind.c +@@ -52,6 +52,20 @@ sr_parse_coredump(const char *coredump_filename, + + #endif /* !defined WITH_LIBDWFL && !defined WITH_LIBUNWIND */ + ++#if !defined WITH_LIBDWFL ++ ++struct sr_core_stacktrace * ++sr_core_stacktrace_from_core_hook(pid_t thread_id, ++ const char *executable_filename, ++ int signum, ++ char **error_message); ++{ ++ *error_message = sr_asprintf("satyr is built without live process unwind support"); ++ return NULL; ++} ++ ++#endif /* !defined WITH_LIBDWFL */ ++ + /* FIXME: is there another way to pass the executable name to the find_elf + * callback? */ + const char *executable_file = NULL; +diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c +index bbd4813..bea9b5f 100644 +--- a/lib/core_unwind_elfutils.c ++++ b/lib/core_unwind_elfutils.c +@@ -28,6 +28,10 @@ + + #include + #include ++#include ++#include ++#include ++#include + + #define FRAME_LIMIT 256 + +@@ -202,4 +206,136 @@ fail: + return stacktrace; + } + ++struct sr_core_stacktrace * ++sr_core_stacktrace_from_core_hook(pid_t tid, ++ const char *executable, ++ int signum, ++ char **error_msg) ++{ ++ struct sr_core_stacktrace *stacktrace = NULL; ++ ++ /* Initialize error_msg to 'no error'. */ ++ if (error_msg) ++ *error_msg = NULL; ++ ++ const Dwfl_Callbacks proc_cb = ++ { ++ .find_elf = dwfl_linux_proc_find_elf, ++ .find_debuginfo = find_debuginfo_none, ++ }; ++ ++ Dwfl *dwfl = dwfl_begin(&proc_cb); ++ ++ if (dwfl_linux_proc_report(dwfl, tid) != 0) ++ { ++ set_error_dwfl("dwfl_linux_proc_report"); ++ goto fail; ++ } ++ ++ if (dwfl_report_end(dwfl, NULL, NULL) != 0) ++ { ++ set_error_dwfl("dwfl_report_end"); ++ goto fail; ++ } ++ ++ if (ptrace(PTRACE_SEIZE, tid, NULL, (void *)(uintptr_t)PTRACE_O_TRACEEXIT) != 0) ++ { ++ set_error("PTRACE_SEIZE (tid %u) failed: %s", (unsigned)tid, strerror(errno)); ++ goto fail; ++ } ++ ++ if (close(STDIN_FILENO) != 0) ++ { ++ set_error("Failed to close stdin: %s", strerror(errno)); ++ goto fail; ++ } ++ ++ int status; ++ pid_t got = waitpid(tid, &status, 0); ++ if (got == -1) ++ { ++ set_error("waitpid failed: %s", strerror(errno)); ++ goto fail; ++ } ++ ++ if (got != tid) ++ { ++ set_error("waitpid returned %u but %u was expected", (unsigned)got, (unsigned)tid); ++ goto fail; ++ } ++ ++ if (!WIFSTOPPED(status)) ++ { ++ set_error("waitpid returned 0x%x but WIFSTOPPED was expected", status); ++ goto fail; ++ } ++ ++ if ((status >> 8) != (SIGTRAP | (PTRACE_EVENT_EXIT << 8))) ++ { ++ set_error("waitpid returned 0x%x but (status >> 8) == " ++ "(SIGTRAP | (PTRACE_EVENT_EXIT << 8)) was expected", status); ++ goto fail; ++ } ++ ++ if (dwfl_linux_proc_attach(dwfl, tid, true) != 0) ++ { ++ set_error_dwfl("dwfl_linux_proc_attach"); ++ goto fail; ++ } ++ ++ stacktrace = sr_core_stacktrace_new(); ++ if (!stacktrace) ++ { ++ set_error("Failed to initialize stacktrace memory"); ++ goto fail; ++ } ++ ++ stacktrace->threads = sr_core_thread_new(); ++ if (!stacktrace->threads) ++ { ++ set_error("Failed to initialize thread memory"); ++ sr_core_stacktrace_free(stacktrace); ++ stacktrace = 0; ++ goto fail; ++ } ++ stacktrace->threads->id = tid; ++ ++ struct frame_callback_arg frame_arg = ++ { ++ .frames_tail = &(stacktrace->threads->frames), ++ .error_msg = NULL, ++ .nframes = 0 ++ }; ++ ++ int ret = dwfl_getthread_frames(dwfl, tid, frame_callback, &frame_arg); ++ if (ret != 0 && ret != CB_STOP_UNWIND) ++ { ++ if (ret == -1) ++ set_error_dwfl("dwfl_getthread_frames"); ++ else if (ret == DWARF_CB_ABORT) ++ { ++ set_error("%s", frame_arg.error_msg); ++ free(frame_arg.error_msg); ++ } ++ else ++ set_error("Unknown error in dwfl_getthreads"); ++ ++ sr_core_stacktrace_free(stacktrace); ++ stacktrace = NULL; ++ goto fail; ++ } ++ ++ truncate_long_thread(stacktrace->threads, &frame_arg); ++ ++ if (executable) ++ stacktrace->executable = sr_strdup(executable); ++ if (signum > 0) ++ stacktrace->signal = (uint16_t)signum; ++ stacktrace->crash_thread = stacktrace->threads; ++ ++fail: ++ dwfl_end(dwfl); ++ return stacktrace; ++} ++ + #endif /* WITH_LIBDWFL */ +-- +2.4.3 + diff --git a/SOURCES/satyr-0.13-unwind-minor-refactoring.patch b/SOURCES/satyr-0.13-unwind-minor-refactoring.patch new file mode 100644 index 0000000..3c392cb --- /dev/null +++ b/SOURCES/satyr-0.13-unwind-minor-refactoring.patch @@ -0,0 +1,94 @@ +From f8be518c5d8534f8724c752c6ad95b3e61460a7b Mon Sep 17 00:00:00 2001 +From: Martin Milata +Date: Mon, 24 Nov 2014 14:34:09 +0100 +Subject: [PATCH 2/5] unwind: minor refactoring + +Related to abrt/abrt#829. + +Signed-off-by: Martin Milata +--- + lib/core_unwind.c | 2 +- + lib/core_unwind_elfutils.c | 24 +++++++++++++++--------- + lib/internal_unwind.h | 6 ++++++ + 3 files changed, 22 insertions(+), 10 deletions(-) + +diff --git a/lib/core_unwind.c b/lib/core_unwind.c +index 8b7cc22..48d5ca5 100644 +--- a/lib/core_unwind.c ++++ b/lib/core_unwind.c +@@ -127,7 +127,7 @@ find_elf_core (Dwfl_Module *mod, void **userdata, const char *modname, + } + + /* Do not use debuginfo files at all. */ +-static int ++int + find_debuginfo_none (Dwfl_Module *mod, void **userdata, const char *modname, + GElf_Addr base, const char *file_name, + const char *debuglink_file, GElf_Word debuglink_crc, +diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c +index bbd4813..8351ebf 100644 +--- a/lib/core_unwind_elfutils.c ++++ b/lib/core_unwind_elfutils.c +@@ -77,6 +77,19 @@ frame_callback(Dwfl_Frame *frame, void *data) + return DWARF_CB_OK; + } + ++static void ++truncate_long_thread(struct sr_core_thread *thread, struct frame_callback_arg *frame_arg) ++{ ++ /* Truncate the stacktrace to FRAME_LIMIT least recent frames. */ ++ while (thread->frames && frame_arg->nframes > FRAME_LIMIT) ++ { ++ struct sr_core_frame *old_frame = thread->frames; ++ thread->frames = old_frame->next; ++ sr_core_frame_free(old_frame); ++ frame_arg->nframes--; ++ } ++} ++ + static int + unwind_thread(Dwfl_Thread *thread, void *data) + { +@@ -86,7 +99,7 @@ unwind_thread(Dwfl_Thread *thread, void *data) + struct sr_core_thread *result = sr_core_thread_new(); + if (!result) + { +- set_error("Failed to initialize stacktrace memory"); ++ set_error("Failed to initialize thread memory"); + return DWARF_CB_ABORT; + } + result->id = (int64_t)dwfl_thread_tid(thread); +@@ -121,14 +134,7 @@ unwind_thread(Dwfl_Thread *thread, void *data) + goto abort; + } + +- /* Truncate the stacktrace to FRAME_LIMIT least recent frames. */ +- while (result->frames && frame_arg.nframes > FRAME_LIMIT) +- { +- struct sr_core_frame *old_frame = result->frames; +- result->frames = old_frame->next; +- sr_core_frame_free(old_frame); +- frame_arg.nframes--; +- } ++ truncate_long_thread(result, &frame_arg); + + *thread_arg->threads_tail = result; + thread_arg->threads_tail = &result->next; +diff --git a/lib/internal_unwind.h b/lib/internal_unwind.h +index 2c9abb7..84261c6 100644 +--- a/lib/internal_unwind.h ++++ b/lib/internal_unwind.h +@@ -96,4 +96,10 @@ resolve_frame(Dwfl *dwfl, Dwarf_Addr ip, bool minus_one); + short + get_signal_number(Elf *e, const char *elf_file); + ++int ++find_debuginfo_none (Dwfl_Module *mod, void **userdata, const char *modname, ++ GElf_Addr base, const char *file_name, ++ const char *debuglink_file, GElf_Word debuglink_crc, ++ char **debuginfo_file_name); ++ + #endif /* SATYR_INTERNAL_UNWIND_H */ +-- +2.4.3 + diff --git a/SPECS/satyr.spec b/SPECS/satyr.spec index b4ad206..41b18e5 100644 --- a/SPECS/satyr.spec +++ b/SPECS/satyr.spec @@ -19,7 +19,7 @@ Name: satyr Version: 0.13 -Release: 8%{?dist} +Release: 12%{?dist} Summary: Tools to create anonymous, machine-friendly problem reports Group: System Environment/Libraries License: GPLv2+ @@ -70,6 +70,15 @@ Patch11: satyr-0.13-dont-free-gdb-stacktrace.patch # 1142346, better handling of infinite recursion Patch12: satyr-0.13-better-inf-recursion-handling.patch +# 1210599, add functionality to generate a backtrace without saving a coredump +Patch13: satyr-0.13-fulfill-missing-values-in-core-frames.patch +Patch14: satyr-0.13-unwind-minor-refactoring.patch +Patch15: satyr-0.13-support-unwinding-from-core-hook.patch +Patch16: satyr-0.13-debug-unwinding-from-core-hook-using-satyr-binary.patch +Patch17: satyr-0.13-disable-hook-unwind-on-kernels-w-o-PTRACE_SEIZE.patch +Patch18: satyr-0.13-abrt-refactorize-unwinding-from-core-hook.patch +Patch19: satyr-0.13-core_unwind-fix-the-missing-frame-build_id-and-file.patch + %description Satyr is a library that can be used to create and process microreports. Microreports consist of structured data suitable to be analyzed in a fully @@ -110,6 +119,13 @@ Python bindings for %{name}. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 %build %configure \ @@ -152,6 +168,22 @@ make check %endif %changelog +* Wed Sep 9 2015 Richard Marko - 0.13-12 +- apply last patch + - Related: #1210599 + +* Wed Sep 9 2015 Richard Marko - 0.13-11 +- core unwind: fix the missing frame build_id and file_name + - Related: #1210599 + +* Fri Jul 17 2015 Richard Marko - 0.13-10 +- leave saving of core backtrace to abrt hook + - Related: #1210599 + +* Tue Jun 23 2015 Richard Marko - 0.13-9 +- Add functionality to generate a backtrace without saving a coredump + - Resolves: #1210599 + * Wed Nov 19 2014 Martin Milata - 0.13-8 - Better handling of stacktraces with infinite recursion - Resolves: #1142346