[SATYR PATCH 5/5] Add function for creating core stacktrace from gdb

Martin Milata mmilata at redhat.com
Wed Jul 24 13:55:08 UTC 2013


Needed as on some distributions there is neither libunwind nor elfutils
with unwinder.

Signed-off-by: Martin Milata <mmilata at redhat.com>
---
 include/core/unwind.h |  7 ++++++
 lib/core_unwind.c     | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/include/core/unwind.h b/include/core/unwind.h
index 55af5a5..8ab9d52 100644
--- a/include/core/unwind.h
+++ b/include/core/unwind.h
@@ -25,12 +25,19 @@ extern "C" {
 #endif
 
 struct sr_core_stacktrace;
+struct sr_gdb_stacktrace;
 
 struct sr_core_stacktrace *
 sr_parse_coredump(const char *coredump_filename,
                   const char *executable_filename,
                   char **error_message);
 
+struct sr_core_stacktrace *
+sr_core_stacktrace_from_gdb(const char *gdb_output,
+                            const char *coredump_filename,
+                            const char *executable_filename,
+                            char **error_message);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/core_unwind.c b/lib/core_unwind.c
index b8cd266..f15a0f9 100644
--- a/lib/core_unwind.c
+++ b/lib/core_unwind.c
@@ -30,6 +30,14 @@
 #include "core/unwind.h"
 #include "internal_unwind.h"
 
+#include "location.h"
+#include "gdb/frame.h"
+#include "gdb/thread.h"
+#include "gdb/stacktrace.h"
+#include "core/frame.h"
+#include "core/thread.h"
+#include "core/stacktrace.h"
+
 #if !defined WITH_LIBDWFL && !defined WITH_LIBUNWIND
 
 struct sr_core_stacktrace *
@@ -377,4 +385,64 @@ get_signal_number(Elf *e, const char *elf_file)
     return 0;
 }
 
+struct sr_core_stacktrace *
+sr_core_stacktrace_from_gdb(const char *gdb_output, const char *core_file,
+                            const char *exe_file, char **error_msg)
+{
+    /* Initialize error_msg to 'no error'. */
+    if (error_msg)
+        *error_msg = NULL;
+
+    struct core_handle *ch = open_coredump(core_file, exe_file, error_msg);
+    if (*error_msg)
+        return NULL;
+
+    struct sr_gdb_stacktrace *gdb_stacktrace;
+    struct sr_location location;
+    sr_location_init(&location);
+
+    gdb_stacktrace = sr_gdb_stacktrace_parse(&gdb_output, &location);
+    if (!gdb_stacktrace)
+    {
+        *error_msg = sr_location_to_string(&location);
+        core_handle_free(ch);
+        return NULL;
+    }
+
+    struct sr_core_stacktrace *core_stacktrace = sr_core_stacktrace_new();
+
+    for (struct sr_gdb_thread *gdb_thread = gdb_stacktrace->threads;
+         gdb_thread;
+         gdb_thread = gdb_thread->next)
+    {
+        struct sr_core_thread *core_thread = sr_core_thread_new();
+
+        for (struct sr_gdb_frame *gdb_frame = gdb_thread->frames;
+             gdb_frame;
+             gdb_frame = gdb_frame->next)
+        {
+            struct sr_core_frame *core_frame = resolve_frame(ch->dwfl,
+                    gdb_frame->address, false);
+
+            core_thread->frames = sr_core_frame_append(core_thread->frames,
+                    core_frame);
+        }
+
+        if (sr_gdb_stacktrace_find_crash_thread(gdb_stacktrace) == gdb_thread)
+        {
+            core_stacktrace->crash_thread = core_thread;
+        }
+
+        core_stacktrace->threads = sr_core_thread_append(
+                core_stacktrace->threads, core_thread);
+    }
+
+    core_stacktrace->signal = get_signal_number(ch->eh, core_file);
+    core_stacktrace->executable = realpath(exe_file, NULL);
+
+    core_handle_free(ch);
+    sr_gdb_stacktrace_free(gdb_stacktrace);
+    return core_stacktrace;
+}
+
 #endif /* !defined WITH_LIBDWFL && !defined WITH_LIBUNWIND */
-- 
1.7.11.7



More information about the Crash-catcher mailing list