From d7ddc6a4e225e7c8cc5e25d801687911d8136894 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 05:05:59 +0000 Subject: import satyr-0.13-15.el7 --- diff --git a/SOURCES/satyr-0.13-Honor-frame-number-limit-in-GDB-core-unwinder.patch b/SOURCES/satyr-0.13-Honor-frame-number-limit-in-GDB-core-unwinder.patch new file mode 100644 index 0000000..e0aeed1 --- /dev/null +++ b/SOURCES/satyr-0.13-Honor-frame-number-limit-in-GDB-core-unwinder.patch @@ -0,0 +1,90 @@ +From d94a7b5c516c0446d1c49e8446707a64b4b45148 Mon Sep 17 00:00:00 2001 +From: Jakub Filak +Date: Tue, 2 Aug 2016 08:50:10 +0200 +Subject: [PATCH] Honor frame number limit in GDB core unwinder + +Related to #1260074 + +Signed-off-by: Jakub Filak +--- + lib/core_unwind.c | 15 +++++++++++++++ + lib/core_unwind_elfutils.c | 6 ++---- + lib/internal_unwind.h | 5 +++++ + 3 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/lib/core_unwind.c b/lib/core_unwind.c +index b8c0235..05b94a5 100644 +--- a/lib/core_unwind.c ++++ b/lib/core_unwind.c +@@ -429,6 +429,8 @@ sr_core_stacktrace_from_gdb(const char *gdb_output, const char *core_file, + { + struct sr_core_thread *core_thread = sr_core_thread_new(); + ++ unsigned long nframes = CORE_STACKTRACE_FRAME_LIMIT; ++ struct sr_gdb_frame *top_frame = gdb_thread->frames; + for (struct sr_gdb_frame *gdb_frame = gdb_thread->frames; + gdb_frame; + gdb_frame = gdb_frame->next) +@@ -436,6 +438,19 @@ sr_core_stacktrace_from_gdb(const char *gdb_output, const char *core_file, + if (gdb_frame->signal_handler_called) + continue; + ++ if (nframes) ++ --nframes; ++ else ++ top_frame = top_frame->next; ++ } ++ ++ for (struct sr_gdb_frame *gdb_frame = top_frame; ++ 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); + +diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c +index 1482dba..d273a03 100644 +--- a/lib/core_unwind_elfutils.c ++++ b/lib/core_unwind_elfutils.c +@@ -33,8 +33,6 @@ + #include + #include + +-#define FRAME_LIMIT 256 +- + struct frame_callback_arg + { + struct sr_core_frame **frames_tail; +@@ -84,8 +82,8 @@ frame_callback(Dwfl_Frame *frame, void *data) + 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) ++ /* Truncate the stacktrace to CORE_STACKTRACE_FRAME_LIMIT least recent frames. */ ++ while (thread->frames && frame_arg->nframes > CORE_STACKTRACE_FRAME_LIMIT) + { + struct sr_core_frame *old_frame = thread->frames; + thread->frames = old_frame->next; +diff --git a/lib/internal_unwind.h b/lib/internal_unwind.h +index 84261c6..b9e162a 100644 +--- a/lib/internal_unwind.h ++++ b/lib/internal_unwind.h +@@ -66,6 +66,11 @@ _set_error(char **error_msg, const char *fmt, ...) __sr_printf(2, 3); + } \ + } while(0) + ++/* This macro is used as a limit for the number of function frames included in ++ * every single thread of a core stacktrace generated by satyr. ++ */ ++#define CORE_STACKTRACE_FRAME_LIMIT 256 ++ + struct exe_mapping_data + { + uint64_t start; +-- +2.17.1 + diff --git a/SOURCES/satyr-0.13-testsuite-add-test-for-limit-frame-number-in-GDB-cor.patch b/SOURCES/satyr-0.13-testsuite-add-test-for-limit-frame-number-in-GDB-cor.patch new file mode 100644 index 0000000..0cfcc61 --- /dev/null +++ b/SOURCES/satyr-0.13-testsuite-add-test-for-limit-frame-number-in-GDB-cor.patch @@ -0,0 +1,182 @@ +From 77243901ca72e4f49ed650eecfe501edfb2344df Mon Sep 17 00:00:00 2001 +From: Matej Habrnal +Date: Tue, 30 Aug 2016 11:09:50 +0200 +Subject: [PATCH] testsuite: add test for limit frame number in GDB core + unwinder + +Related to #1260074 + +Signed-off-by: Matej Habrnal +--- + tests/core_stacktrace.at | 158 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 158 insertions(+) + +diff --git a/tests/core_stacktrace.at b/tests/core_stacktrace.at +index f45e126..313d8b8 100644 +--- a/tests/core_stacktrace.at ++++ b/tests/core_stacktrace.at +@@ -197,3 +197,161 @@ main(void) + return 0; + } + ]]) ++ ++## --------------------------------- ## ++## sr_core_stacktrace_from_gdb_limit ## ++## --------------------------------- ## ++ ++AT_TESTFUN([sr_core_stacktrace_from_gdb_limit], ++[[ ++#define _GNU_SOURCE ++#include "stacktrace.h" ++#include "core/stacktrace.h" ++#include "core/thread.h" ++#include "core/frame.h" ++#include "core/unwind.h" ++#include "strbuf.h" ++#include "utils.h" ++#include "report_type.h" ++#include ++#include ++#include "internal_unwind.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++char *generate_coredump(int start) ++{ ++ ++ if (start) ++ { ++ return generate_coredump(--start); ++ } ++ ++ const char* coredump_pattern = "/tmp/satyr.core"; ++ ++ char *mypid = NULL; ++ asprintf(&mypid, "%d", getpid()); ++ if (mypid == NULL) ++ err(1, "asprintf"); ++ ++ pid_t pid = fork(); ++ if (pid < 0) ++ err(1, "fork"); ++ if (pid == 0) ++ { ++ char *args[] = { "gcore", "-o", (char *)coredump_pattern, mypid, NULL }; ++ execv("/usr/bin/gcore", args); ++ } ++ ++ int status; ++ int r; ++ while ((r = waitpid(pid, &status, 0)) < 0) ++ { ++ if (errno != EAGAIN) ++ err(1, "waitpid"); ++ } ++ ++ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) ++ errx(1, "gcore failed"); ++ ++ return sr_asprintf("%s.%s", coredump_pattern, mypid); ++} ++struct sr_strbuf * ++get_backtrace(const char *core_file, const char *executable) ++{ ++ unsigned i = 0; ++ char *args[25]; ++ args[i++] = (char*)"/usr/bin/gdb"; ++ args[i++] = (char*)"-batch"; ++ args[i++] = (char*)"-iex"; ++ args[i++] = (char*)"set debug-file-directory /"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = sr_asprintf("file %s", executable); ++ args[i++] = (char*)"-ex"; ++ args[i++] = sr_asprintf("core-file %s", core_file); ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"thread apply all backtrace 1024 full"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"info sharedlib"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"print (char*)__abort_msg"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"print (char*)__glib_assert_msg"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"info all-registers"; ++ args[i++] = (char*)"-ex"; ++ args[i++] = (char*)"disassemble"; ++ args[i++] = NULL; ++ ++ int p[2]; ++ int pipe_return = pipe(p); ++ if (pipe_return != 0) ++ err(1, "pipe"); ++ ++ pid_t pid = fork(); ++ if (pid < 0) ++ err(1, "fork"); ++ if (pid == 0) /* child */ ++ { ++ close(p[0]); ++ dup2(p[1], 1); // send stdout to the pipe ++ dup2(p[1], 2); // send stderr to the pipe ++ ++ execv(args[0], args); ++ } ++ close(p[1]); ++ ++ struct sr_strbuf *gdb_buf = sr_strbuf_new(); ++ sr_strbuf_init(gdb_buf); ++ char buf[256]; ++ ssize_t size; ++ while((size = read(p[0], buf, sizeof(buf)-1)) > 0 && errno != EINTR) ++ { ++ buf[size] = '\0'; ++ sr_strbuf_append_str(gdb_buf, (const char*) buf); ++ } ++ ++ int status, r; ++ while ((r = waitpid(pid, &status, 0)) < 0) ++ { ++ if (errno != EAGAIN) ++ err(1, "waitpid"); ++ } ++ ++ return gdb_buf; ++} ++ ++int ++main(int argc, char* argv[]) ++{ ++ char *coredump_path = generate_coredump(257); ++ ++ struct sr_strbuf *gdb_output = get_backtrace(coredump_path, argv[0]); ++ assert(gdb_output); ++ assert(gdb_output->buf); ++ ++ char *error_msg = NULL; ++ struct sr_core_stacktrace *core_stacktrace = sr_core_stacktrace_from_gdb(gdb_output->buf, coredump_path, argv[0], &error_msg); ++ assert(!error_msg); ++ ++ struct sr_core_thread *threads = core_stacktrace->threads; ++ struct sr_core_frame *frames = threads->frames; ++ unsigned nframes = 0; ++ for(; frames; ++nframes, frames = frames->next) ++ ; ++ ++ /* max num of frames is CORE_STACKTRACE_FRAME_LIMIT */ ++ assert(nframes == CORE_STACKTRACE_FRAME_LIMIT); ++ ++ free(coredump_path); ++ sr_strbuf_free(gdb_output); ++ ++ return 0; ++} ++]]) +-- +2.17.1 + diff --git a/SPECS/satyr.spec b/SPECS/satyr.spec index f0cf641..ee2824a 100644 --- a/SPECS/satyr.spec +++ b/SPECS/satyr.spec @@ -19,7 +19,7 @@ Name: satyr Version: 0.13 -Release: 14%{?dist} +Release: 15%{?dist} Summary: Tools to create anonymous, machine-friendly problem reports Group: System Environment/Libraries License: GPLv2+ @@ -106,6 +106,10 @@ Patch30: satyr-0.13-Check-the-return-value-of-sr_parse_char_cspan.patch # 1342469, support for VARIANT and VARIANT_ID Patch31: satyr-0.13-os-add-support-for-OS-Variant.patch +# 1260074, Incorrectly unwinding core_backtrace for stack overflow (aarch64) +Patch32: satyr-0.13-Honor-frame-number-limit-in-GDB-core-unwinder.patch +Patch33: satyr-0.13-testsuite-add-test-for-limit-frame-number-in-GDB-cor.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 @@ -188,6 +192,10 @@ make check || { %endif %changelog +* Tue Jun 19 2018 Matej Marusak - 0.13-15 +- Honor frame number limit in GDB core unwinder + - Related: #1260074 + * Mon Jun 06 2016 Matej Habrnal - 0.13-14 - add support for OS Variant - Related: #1342469