mfabik / rpms / satyr

Forked from rpms/satyr 3 years ago
Clone

Blame SOURCES/satyr-0.13-better-inf-recursion-handling.patch

f41043
From 9639948f3fdda4afcf25e7080aa87d8ad2fbeb34 Mon Sep 17 00:00:00 2001
f41043
From: Martin Milata <mmilata@redhat.com>
f41043
Date: Wed, 27 Aug 2014 13:55:50 +0200
f41043
Subject: [SATYR PATCH] Better handling of infinite recursion
f41043
f41043
unwind: Append threads/frames in O(1)
f41043
unwind: throw away the most recent frames
f41043
unwind: lower stacktrace length limit to 256
f41043
f41043
Fixes #179.
f41043
f41043
Signed-off-by: Martin Milata <mmilata@redhat.com>
f41043
---
f41043
 lib/core_unwind_elfutils.c | 36 ++++++++++++++++++++----------------
f41043
 1 file changed, 20 insertions(+), 16 deletions(-)
f41043
f41043
diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c
f41043
index 43d66be..bbd4813 100644
f41043
--- a/lib/core_unwind_elfutils.c
f41043
+++ b/lib/core_unwind_elfutils.c
f41043
@@ -29,18 +29,18 @@
f41043
 #include <stdio.h>
f41043
 #include <string.h>
f41043
 
f41043
-#define FRAME_LIMIT 1024
f41043
+#define FRAME_LIMIT 256
f41043
 
f41043
 struct frame_callback_arg
f41043
 {
f41043
-    struct sr_core_thread *thread;
f41043
+    struct sr_core_frame **frames_tail;
f41043
     char *error_msg;
f41043
     unsigned nframes;
f41043
 };
f41043
 
f41043
 struct thread_callback_arg
f41043
 {
f41043
-    struct sr_core_stacktrace *stacktrace;
f41043
+    struct sr_core_thread **threads_tail;
f41043
     char *error_msg;
f41043
 };
f41043
 
f41043
@@ -70,15 +70,9 @@ frame_callback(Dwfl_Frame *frame, void *data)
f41043
         return CB_STOP_UNWIND;
f41043
     }
f41043
 
f41043
-    frame_arg->thread->frames =
f41043
-        sr_core_frame_append(frame_arg->thread->frames, result);
f41043
-
f41043
-    /* Avoid huge stacktraces from programs stuck in infinite recursion. */
f41043
+    *frame_arg->frames_tail = result;
f41043
+    frame_arg->frames_tail = &result->next;
f41043
     frame_arg->nframes++;
f41043
-    if (frame_arg->nframes >= FRAME_LIMIT)
f41043
-    {
f41043
-        return CB_STOP_UNWIND;
f41043
-    }
f41043
 
f41043
     return DWARF_CB_OK;
f41043
 }
f41043
@@ -99,7 +93,7 @@ unwind_thread(Dwfl_Thread *thread, void *data)
f41043
 
f41043
     struct frame_callback_arg frame_arg =
f41043
     {
f41043
-        .thread = result,
f41043
+        .frames_tail = &(result->frames),
f41043
         .error_msg = NULL,
f41043
         .nframes = 0
f41043
     };
f41043
@@ -121,14 +115,24 @@ unwind_thread(Dwfl_Thread *thread, void *data)
f41043
         goto abort;
f41043
     }
f41043
 
f41043
-    if (!error_msg && !frame_arg.thread->frames)
f41043
+    if (!error_msg && !result->frames)
f41043
     {
f41043
         set_error("No frames found for thread id %d", (int)result->id);
f41043
         goto abort;
f41043
     }
f41043
 
f41043
-    thread_arg->stacktrace->threads =
f41043
-        sr_core_thread_append(thread_arg->stacktrace->threads, result);
f41043
+    /* Truncate the stacktrace to FRAME_LIMIT least recent frames. */
f41043
+    while (result->frames && frame_arg.nframes > FRAME_LIMIT)
f41043
+    {
f41043
+        struct sr_core_frame *old_frame = result->frames;
f41043
+        result->frames = old_frame->next;
f41043
+        sr_core_frame_free(old_frame);
f41043
+        frame_arg.nframes--;
f41043
+    }
f41043
+
f41043
+    *thread_arg->threads_tail = result;
f41043
+    thread_arg->threads_tail = &result->next;
f41043
+
f41043
     return DWARF_CB_OK;
f41043
 
f41043
 abort:
f41043
@@ -166,7 +170,7 @@ sr_parse_coredump(const char *core_file,
f41043
 
f41043
     struct thread_callback_arg thread_arg =
f41043
     {
f41043
-        .stacktrace = stacktrace,
f41043
+        .threads_tail = &(stacktrace->threads),
f41043
         .error_msg = NULL
f41043
     };
f41043
 
f41043
-- 
f41043
1.9.3
f41043