mfabik / rpms / satyr

Forked from rpms/satyr 3 years ago
Clone

Blame SOURCES/satyr-0.13-testsuite-add-test-for-limit-frame-number-in-GDB-cor.patch

01add4
From 77243901ca72e4f49ed650eecfe501edfb2344df Mon Sep 17 00:00:00 2001
01add4
From: Matej Habrnal <mhabrnal@redhat.com>
01add4
Date: Tue, 30 Aug 2016 11:09:50 +0200
01add4
Subject: [PATCH] testsuite: add test for limit frame number in GDB core
01add4
 unwinder
01add4
01add4
Related to #1260074
01add4
01add4
Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
01add4
---
01add4
 tests/core_stacktrace.at | 158 +++++++++++++++++++++++++++++++++++++++
01add4
 1 file changed, 158 insertions(+)
01add4
01add4
diff --git a/tests/core_stacktrace.at b/tests/core_stacktrace.at
01add4
index f45e126..313d8b8 100644
01add4
--- a/tests/core_stacktrace.at
01add4
+++ b/tests/core_stacktrace.at
01add4
@@ -197,3 +197,161 @@ main(void)
01add4
   return 0;
01add4
 }
01add4
 ]])
01add4
+
01add4
+## --------------------------------- ##
01add4
+## sr_core_stacktrace_from_gdb_limit ##
01add4
+## --------------------------------- ##
01add4
+
01add4
+AT_TESTFUN([sr_core_stacktrace_from_gdb_limit],
01add4
+[[
01add4
+#define _GNU_SOURCE
01add4
+#include "stacktrace.h"
01add4
+#include "core/stacktrace.h"
01add4
+#include "core/thread.h"
01add4
+#include "core/frame.h"
01add4
+#include "core/unwind.h"
01add4
+#include "strbuf.h"
01add4
+#include "utils.h"
01add4
+#include "report_type.h"
01add4
+#include <assert.h>
01add4
+#include <stdio.h>
01add4
+#include "internal_unwind.h"
01add4
+#include <stdlib.h>
01add4
+#include <unistd.h>
01add4
+#include <sys/types.h>
01add4
+#include <sys/wait.h>
01add4
+#include <errno.h>
01add4
+#include <err.h>
01add4
+#include <unistd.h>
01add4
+#include <fcntl.h>
01add4
+
01add4
+char *generate_coredump(int start)
01add4
+{
01add4
+
01add4
+  if (start)
01add4
+  {
01add4
+      return generate_coredump(--start);
01add4
+  }
01add4
+
01add4
+  const char* coredump_pattern = "/tmp/satyr.core";
01add4
+
01add4
+  char *mypid = NULL;
01add4
+  asprintf(&mypid, "%d", getpid());
01add4
+  if (mypid == NULL)
01add4
+      err(1, "asprintf");
01add4
+
01add4
+  pid_t pid = fork();
01add4
+  if (pid < 0)
01add4
+      err(1, "fork");
01add4
+  if (pid == 0)
01add4
+  {
01add4
+      char *args[] = { "gcore", "-o", (char *)coredump_pattern, mypid, NULL };
01add4
+      execv("/usr/bin/gcore", args);
01add4
+  }
01add4
+
01add4
+  int status;
01add4
+  int r;
01add4
+  while ((r = waitpid(pid, &status, 0)) < 0)
01add4
+  {
01add4
+      if (errno != EAGAIN)
01add4
+          err(1, "waitpid");
01add4
+  }
01add4
+
01add4
+  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
01add4
+      errx(1, "gcore failed");
01add4
+
01add4
+  return sr_asprintf("%s.%s", coredump_pattern, mypid);
01add4
+}
01add4
+struct sr_strbuf *
01add4
+get_backtrace(const char *core_file, const char *executable)
01add4
+{
01add4
+  unsigned i = 0;
01add4
+  char *args[25];
01add4
+  args[i++] = (char*)"/usr/bin/gdb";
01add4
+  args[i++] = (char*)"-batch";
01add4
+  args[i++] = (char*)"-iex";
01add4
+  args[i++] = (char*)"set debug-file-directory /";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = sr_asprintf("file %s", executable);
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = sr_asprintf("core-file %s", core_file);
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"thread apply all backtrace 1024 full";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"info sharedlib";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"print (char*)__abort_msg";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"print (char*)__glib_assert_msg";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"info all-registers";
01add4
+  args[i++] = (char*)"-ex";
01add4
+  args[i++] = (char*)"disassemble";
01add4
+  args[i++] = NULL;
01add4
+
01add4
+  int p[2];
01add4
+  int pipe_return = pipe(p);
01add4
+  if (pipe_return != 0)
01add4
+      err(1, "pipe");
01add4
+
01add4
+  pid_t pid = fork();
01add4
+  if (pid < 0)
01add4
+      err(1, "fork");
01add4
+  if (pid == 0) /* child */
01add4
+  {
01add4
+    close(p[0]);
01add4
+    dup2(p[1], 1);  // send stdout to the pipe
01add4
+    dup2(p[1], 2);  // send stderr to the pipe
01add4
+
01add4
+    execv(args[0], args);
01add4
+  }
01add4
+  close(p[1]);
01add4
+
01add4
+  struct sr_strbuf *gdb_buf = sr_strbuf_new();
01add4
+  sr_strbuf_init(gdb_buf);
01add4
+  char buf[256];
01add4
+  ssize_t size;
01add4
+  while((size = read(p[0], buf, sizeof(buf)-1)) > 0 && errno != EINTR)
01add4
+  {
01add4
+    buf[size] = '\0';
01add4
+    sr_strbuf_append_str(gdb_buf, (const char*) buf);
01add4
+  }
01add4
+
01add4
+  int status, r;
01add4
+  while ((r = waitpid(pid, &status, 0)) < 0)
01add4
+  {
01add4
+      if (errno != EAGAIN)
01add4
+          err(1, "waitpid");
01add4
+  }
01add4
+
01add4
+  return gdb_buf;
01add4
+}
01add4
+
01add4
+int
01add4
+main(int argc, char* argv[])
01add4
+{
01add4
+  char *coredump_path = generate_coredump(257);
01add4
+
01add4
+  struct sr_strbuf *gdb_output = get_backtrace(coredump_path, argv[0]);
01add4
+  assert(gdb_output);
01add4
+  assert(gdb_output->buf);
01add4
+
01add4
+  char *error_msg = NULL;
01add4
+  struct sr_core_stacktrace *core_stacktrace = sr_core_stacktrace_from_gdb(gdb_output->buf, coredump_path, argv[0], &error_msg);
01add4
+  assert(!error_msg);
01add4
+
01add4
+  struct sr_core_thread *threads = core_stacktrace->threads;
01add4
+  struct sr_core_frame *frames = threads->frames;
01add4
+  unsigned nframes = 0;
01add4
+  for(; frames; ++nframes, frames = frames->next)
01add4
+    ;
01add4
+
01add4
+  /* max num of frames is CORE_STACKTRACE_FRAME_LIMIT */
01add4
+  assert(nframes == CORE_STACKTRACE_FRAME_LIMIT);
01add4
+
01add4
+  free(coredump_path);
01add4
+  sr_strbuf_free(gdb_output);
01add4
+
01add4
+  return 0;
01add4
+}
01add4
+]])
01add4
-- 
01add4
2.17.1
01add4