|
|
0e0bbf |
From 455c47f1f18858c439ff0a0b833ce93c9f79045f Mon Sep 17 00:00:00 2001
|
|
|
0e0bbf |
From: Martin Milata <mmilata@redhat.com>
|
|
|
0e0bbf |
Date: Mon, 24 Nov 2014 14:38:06 +0100
|
|
|
0e0bbf |
Subject: [PATCH 4/5] debug unwinding from core hook using satyr binary
|
|
|
0e0bbf |
|
|
|
0e0bbf |
Write "|/usr/bin/satyr debug unwind-from-hook %e %i %s" to
|
|
|
0e0bbf |
/proc/sys/kernel/core_pattern in order to use this. Before kernel 3.18
|
|
|
0e0bbf |
the %i flag is not available - you can use %p for single-thread
|
|
|
0e0bbf |
processes.
|
|
|
0e0bbf |
|
|
|
0e0bbf |
Related to abrt/abrt#829.
|
|
|
0e0bbf |
|
|
|
0e0bbf |
Signed-off-by: Martin Milata <mmilata@redhat.com>
|
|
|
0e0bbf |
---
|
|
|
0e0bbf |
satyr.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
0e0bbf |
1 file changed, 81 insertions(+)
|
|
|
0e0bbf |
|
|
|
0e0bbf |
diff --git a/satyr.c b/satyr.c
|
|
|
0e0bbf |
index 7bdaa45..6e1ed28 100644
|
|
|
0e0bbf |
--- a/satyr.c
|
|
|
0e0bbf |
+++ b/satyr.c
|
|
|
0e0bbf |
@@ -20,6 +20,8 @@
|
|
|
0e0bbf |
#include "gdb/stacktrace.h"
|
|
|
0e0bbf |
#include "gdb/thread.h"
|
|
|
0e0bbf |
#include "gdb/frame.h"
|
|
|
0e0bbf |
+#include "core/unwind.h"
|
|
|
0e0bbf |
+#include "core/stacktrace.h"
|
|
|
0e0bbf |
#include "utils.h"
|
|
|
0e0bbf |
#include "location.h"
|
|
|
0e0bbf |
#include "strbuf.h"
|
|
|
0e0bbf |
@@ -37,6 +39,7 @@
|
|
|
0e0bbf |
#include <sysexits.h>
|
|
|
0e0bbf |
#include <assert.h>
|
|
|
0e0bbf |
#include <libgen.h>
|
|
|
0e0bbf |
+#include <time.h>
|
|
|
0e0bbf |
|
|
|
0e0bbf |
static char *g_program_name;
|
|
|
0e0bbf |
|
|
|
0e0bbf |
@@ -275,6 +278,82 @@ debug_duphash(int argc, char **argv)
|
|
|
0e0bbf |
}
|
|
|
0e0bbf |
|
|
|
0e0bbf |
static void
|
|
|
0e0bbf |
+debug_unwind_from_hook(int argc, char **argv)
|
|
|
0e0bbf |
+{
|
|
|
0e0bbf |
+ if (argc != 3)
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "Wrong number of arguments.\n");
|
|
|
0e0bbf |
+ fprintf(stderr, "Usage: satyr debug unwind-from-hook "
|
|
|
0e0bbf |
+ "<executable> <tid> <signal>\n");
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ char *executable = argv[0];
|
|
|
0e0bbf |
+ char *end;
|
|
|
0e0bbf |
+ unsigned long tid = strtoul(argv[1], &end, 10);
|
|
|
0e0bbf |
+ if (*end != '\0')
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "Wrong tid\n");
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ unsigned long signum = strtoul(argv[2], &end, 10);
|
|
|
0e0bbf |
+ if (*end != '\0')
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "Wrong signal number\n");
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ char *error_message = NULL;
|
|
|
0e0bbf |
+ struct sr_core_stacktrace *core_stacktrace;
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ core_stacktrace = sr_core_stacktrace_from_core_hook(tid, executable, signum,
|
|
|
0e0bbf |
+ &error_message);
|
|
|
0e0bbf |
+ if (!core_stacktrace)
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "Unwind failed: %s\n", error_message);
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ char *json = sr_core_stacktrace_to_json(core_stacktrace);
|
|
|
0e0bbf |
+ // Add newline to the end of core stacktrace file to make text
|
|
|
0e0bbf |
+ // editors happy.
|
|
|
0e0bbf |
+ json = sr_realloc(json, strlen(json) + 2);
|
|
|
0e0bbf |
+ strcat(json, "\n");
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ time_t t = time(NULL);
|
|
|
0e0bbf |
+ struct tm *tm = localtime(&t);
|
|
|
0e0bbf |
+ char core_backtrace_filename[256];
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ if (tm == NULL)
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ perror("localtime");
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ if (strftime(core_backtrace_filename, sizeof(core_backtrace_filename),
|
|
|
0e0bbf |
+ "/tmp/satyr-core-stacktrace-%F-%T.json", tm) == 0)
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "stftime failed\n");
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ bool success = sr_string_to_file(core_backtrace_filename,
|
|
|
0e0bbf |
+ json,
|
|
|
0e0bbf |
+ &error_message);
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ if (!success)
|
|
|
0e0bbf |
+ {
|
|
|
0e0bbf |
+ fprintf(stderr, "Failed to write stacktrace: %s\n", error_message);
|
|
|
0e0bbf |
+ exit(1);
|
|
|
0e0bbf |
+ }
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+ free(json);
|
|
|
0e0bbf |
+ sr_core_stacktrace_free(core_stacktrace);
|
|
|
0e0bbf |
+}
|
|
|
0e0bbf |
+
|
|
|
0e0bbf |
+static void
|
|
|
0e0bbf |
debug(int argc, char **argv)
|
|
|
0e0bbf |
{
|
|
|
0e0bbf |
/* Debug command requires a subcommand. */
|
|
|
0e0bbf |
@@ -288,6 +367,8 @@ debug(int argc, char **argv)
|
|
|
0e0bbf |
debug_normalize(argc - 1, argv + 1);
|
|
|
0e0bbf |
else if (0 == strcmp(argv[0], "duphash"))
|
|
|
0e0bbf |
debug_duphash(argc - 1, argv + 1);
|
|
|
0e0bbf |
+ else if (0 == strcmp(argv[0], "unwind-from-hook"))
|
|
|
0e0bbf |
+ debug_unwind_from_hook(argc - 1, argv + 1);
|
|
|
0e0bbf |
else
|
|
|
0e0bbf |
{
|
|
|
0e0bbf |
fprintf(stderr, "Unknown debug subcommand.\n");
|
|
|
0e0bbf |
--
|
|
|
0e0bbf |
2.4.3
|
|
|
0e0bbf |
|