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