[commit: ghc] master: rts: Limit maximum backtrace depth (350ffc3)
git at git.haskell.org
git at git.haskell.org
Mon Apr 18 22:01:09 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/350ffc3e4c6b3aefd6ae621991564cc28f585d46/ghc
>---------------------------------------------------------------
commit 350ffc3e4c6b3aefd6ae621991564cc28f585d46
Author: Ben Gamari <ben at smart-cactus.org>
Date: Mon Apr 11 00:49:06 2016 +0200
rts: Limit maximum backtrace depth
This prevents us from entering an infinite loop in the event of a
hitting bad unwinding information.
>---------------------------------------------------------------
350ffc3e4c6b3aefd6ae621991564cc28f585d46
rts/Libdw.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/rts/Libdw.c b/rts/Libdw.c
index 8c3c581..e796840 100644
--- a/rts/Libdw.c
+++ b/rts/Libdw.c
@@ -16,6 +16,8 @@
#include <dwarf.h>
#include <unistd.h>
+const int max_backtrace_depth = 5000;
+
static BacktraceChunk *backtraceAllocChunk(BacktraceChunk *next) {
BacktraceChunk *chunk = stgMallocBytes(sizeof(BacktraceChunk),
"backtraceAllocChunk");
@@ -57,7 +59,10 @@ void backtraceFree(Backtrace *bt) {
struct LibdwSession_ {
Dwfl *dwfl;
- Backtrace *cur_bt; // The current backtrace we are collecting (if any)
+
+ // The current backtrace we are collecting (if any)
+ Backtrace *cur_bt;
+ int max_depth;
};
static const Dwfl_Thread_Callbacks thread_cbs;
@@ -230,8 +235,12 @@ static int getBacktraceFrameCb(Dwfl_Frame *frame, void *arg) {
pc -= 1; // TODO: is this right?
backtracePush(session->cur_bt, (StgPtr) (uintptr_t) pc);
}
-
- return DWARF_CB_OK;
+ session->max_depth--;
+ if (session->max_depth == 0) {
+ return DWARF_CB_ABORT;
+ } else {
+ return DWARF_CB_OK;
+ }
}
Backtrace *libdwGetBacktrace(LibdwSession *session) {
@@ -242,6 +251,7 @@ Backtrace *libdwGetBacktrace(LibdwSession *session) {
Backtrace *bt = backtraceAlloc();
session->cur_bt = bt;
+ session->max_depth = max_backtrace_depth;
int pid = getpid();
int ret = dwfl_getthread_frames(session->dwfl, pid,
More information about the ghc-commits
mailing list