Skip to content

Commit

Permalink
Ignore SEGV during profiler unwind on Unix (#28291)
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt authored and JeffBezanson committed Jul 30, 2018
1 parent 60b8e23 commit 9bb2273
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/signals-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ static void jl_call_in_ctx(jl_ptls_t ptls, void (*fptr)(void), int sig, void *_c
// checks that the syscall is made in the signal handler and that
// the ucontext address is valid. Hopefully the value of the ucontext
// will not be part of the validation...
if (!ptls->signal_stack) {
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, sig);
sigprocmask(SIG_UNBLOCK, &sset, NULL);
fptr();
return;
}
uintptr_t rsp = (uintptr_t)ptls->signal_stack + sig_stack_size;
assert(rsp % 16 == 0);
#if defined(_OS_LINUX_) && defined(_CPU_X86_64_)
Expand Down Expand Up @@ -667,9 +675,22 @@ static void *signal_listener(void *arg)
// do backtrace for profiler
if (profile && running) {
if (bt_size_cur < bt_size_max - 1) {
// Get backtrace data
bt_size_cur += rec_backtrace_ctx((uintptr_t*)bt_data_prof + bt_size_cur,
bt_size_max - bt_size_cur - 1, signal_context);
// unwinding can fail, so keep track of the current state
// and restore from the SEGV handler if anything happens.
jl_ptls_t ptls = jl_get_ptls_states();
jl_jmp_buf *old_buf = ptls->safe_restore;
jl_jmp_buf buf;

ptls->safe_restore = &buf;
if (jl_setjmp(buf, 0)) {
jl_safe_printf("WARNING: profiler attempt to access an invalid memory location\n");
} else {
// Get backtrace data
bt_size_cur += rec_backtrace_ctx((uintptr_t*)bt_data_prof + bt_size_cur,
bt_size_max - bt_size_cur - 1, signal_context);
}
ptls->safe_restore = old_buf;

// Mark the end of this block with 0
bt_data_prof[bt_size_cur++] = 0;
}
Expand Down

0 comments on commit 9bb2273

Please sign in to comment.