Commit b963f07f authored by Ben Gamari's avatar Ben Gamari 🐢
Browse files

rts: Limit maximum backtrace depth

This prevents us from entering an infinite loop in the event of a
hitting bad unwinding information.

(cherry picked from commit 350ffc3e)
parent efafad01
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <dwarf.h> #include <dwarf.h>
#include <unistd.h> #include <unistd.h>
const int max_backtrace_depth = 5000;
static BacktraceChunk *backtraceAllocChunk(BacktraceChunk *next) { static BacktraceChunk *backtraceAllocChunk(BacktraceChunk *next) {
BacktraceChunk *chunk = stgMallocBytes(sizeof(BacktraceChunk), BacktraceChunk *chunk = stgMallocBytes(sizeof(BacktraceChunk),
"backtraceAllocChunk"); "backtraceAllocChunk");
...@@ -57,7 +59,10 @@ void backtraceFree(Backtrace *bt) { ...@@ -57,7 +59,10 @@ void backtraceFree(Backtrace *bt) {
struct LibdwSession_ { struct LibdwSession_ {
Dwfl *dwfl; 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; static const Dwfl_Thread_Callbacks thread_cbs;
...@@ -230,8 +235,12 @@ static int getBacktraceFrameCb(Dwfl_Frame *frame, void *arg) { ...@@ -230,8 +235,12 @@ static int getBacktraceFrameCb(Dwfl_Frame *frame, void *arg) {
pc -= 1; // TODO: is this right? pc -= 1; // TODO: is this right?
backtracePush(session->cur_bt, (StgPtr) (uintptr_t) pc); backtracePush(session->cur_bt, (StgPtr) (uintptr_t) pc);
} }
session->max_depth--;
return DWARF_CB_OK; if (session->max_depth == 0) {
return DWARF_CB_ABORT;
} else {
return DWARF_CB_OK;
}
} }
Backtrace *libdwGetBacktrace(LibdwSession *session) { Backtrace *libdwGetBacktrace(LibdwSession *session) {
...@@ -242,6 +251,7 @@ Backtrace *libdwGetBacktrace(LibdwSession *session) { ...@@ -242,6 +251,7 @@ Backtrace *libdwGetBacktrace(LibdwSession *session) {
Backtrace *bt = backtraceAlloc(); Backtrace *bt = backtraceAlloc();
session->cur_bt = bt; session->cur_bt = bt;
session->max_depth = max_backtrace_depth;
int pid = getpid(); int pid = getpid();
int ret = dwfl_getthread_frames(session->dwfl, pid, int ret = dwfl_getthread_frames(session->dwfl, pid,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment