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