Commit 5efbf4c4 authored by Nils Goroll's avatar Nils Goroll Committed by Pål Hermunn Johansen

use an alternative stack for SIGSEGV and test for stack overflow

Previously, we could run out of stack handling stack overflows, leaving
users with unspecific SIGSEGV crashes and no panic message.

By providing a single alternative stack exclusively for SIGSEGV handling
where sigaltstack() is available, we increase chances for our signal handler
to finish successfully.

In particular, this will make it easier to diagnose stack overflows by
comparing the failing address with the stack info from the panic output.

This could be further improved by giving advise to increase thread_pool_stack
if si_addr is near the stack boundaries.

c00057.vtc now triggers a stack overflow instead of raising a SIGSEGV.

Merges #2396
parent e44e54dc
......@@ -392,9 +392,23 @@ mgt_launch_child(struct cli *cli)
memset(&sa, 0, sizeof sa);
sa.sa_sigaction = child_signal_handler;
sa.sa_flags = SA_SIGINFO;
(void)sigaction(SIGSEGV, &sa, NULL);
(void)sigaction(SIGBUS, &sa, NULL);
(void)sigaction(SIGABRT, &sa, NULL);
#ifdef HAVE_SIGALTSTACK
stack_t ss;
size_t sz = SIGSTKSZ + 4096;
if (sz < mgt_param.wthread_stacksize)
sz = mgt_param.wthread_stacksize;
ss.ss_sp = malloc(sz);
AN(ss.ss_sp);
ss.ss_size = sz;
ss.ss_flags = 0;
AZ(sigaltstack(&ss, NULL));
sa.sa_flags |= SA_ONSTACK;
#endif
(void)sigaction(SIGSEGV, &sa, NULL);
}
(void)signal(SIGINT, SIG_DFL);
(void)signal(SIGTERM, SIG_DFL);
......
......@@ -5,13 +5,32 @@ server s1 {
txresp
} -start
varnish v1 -cliok "param.set vcc_allow_inline_c true"
varnish v1 -vcl+backend {
varnish v1 \
-arg "-p vcc_allow_inline_c=true" \
-arg "-p thread_pool_stack=48k" \
-vcl+backend {
C{
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
static void _accessor(volatile char *p) {
p[0] = 'V'; p[1] = '\0';
fprintf(stderr, "%p %s\n", p, p);
}
void (*accessor)(volatile char *p) = _accessor;
}C
sub vcl_recv { C{ raise(SIGSEGV); sleep(2); }C }
sub vcl_recv { C{
int i;
volatile char overflow[48*1024];
/* for downwards stack, take care to hit a single guard page */
for (i = 47*1024; i >= 0; i -= 1024)
accessor(overflow + i);
/* NOTREACHED */
sleep(2);
}C }
} -start
client c1 {
......
......@@ -258,6 +258,7 @@ AC_CHECK_FUNCS([setppriv])
AC_CHECK_FUNCS([fallocate])
AC_CHECK_FUNCS([closefrom])
AC_CHECK_FUNCS([vsyslog])
AC_CHECK_FUNCS([sigaltstack])
save_LIBS="${LIBS}"
LIBS="${PTHREAD_LIBS}"
......
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