[master] a48b091 Install a SIGSEGV handler

Tollef Fog Heen tfheen at varnish-cache.org
Wed Jul 3 12:11:20 CEST 2013


commit a48b09161fd558489406b198de096705f90f82bf
Author: Tollef Fog Heen <tfheen at varnish-software.com>
Date:   Wed Jul 3 12:06:41 2013 +0200

    Install a SIGSEGV handler
    
    If we happen to get a SIGSEGV, call the panic handler.  It might not
    work, but it's better than nothing and hopefully we can get some
    useful diagnostics.

diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h
index c00d427..dc5f234 100644
--- a/bin/varnishd/common/params.h
+++ b/bin/varnishd/common/params.h
@@ -210,6 +210,9 @@ struct params {
 
 	unsigned		bo_cache;
 
+	/* Install a SIGSEGV handler */
+	unsigned		sigsegv_handler;
+
 	/* VSM dimensions */
 	ssize_t			vsm_space;
 	ssize_t			vsl_space;
diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index 9397891..89e8f4a 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -312,6 +312,25 @@ child_poker(const struct vev *e, int what)
 }
 
 /*=====================================================================
+ * SIGSEGV handler
+ */
+
+static void mgt_sigsegv_handler(int s, siginfo_t *si, void *c) {
+	char buf[1024];
+
+	(void)s;
+	(void)c;
+
+	sprintf(buf, "Segmentation fault by instruction at %p", si->si_addr);
+	VAS_Fail(__func__,
+		 __FILE__,
+		 __LINE__,
+		 buf,
+		 errno,
+		 0);
+}
+
+/*=====================================================================
  * Launch the child process
  */
 
@@ -323,6 +342,7 @@ mgt_launch_child(struct cli *cli)
 	char *p;
 	struct vev *e;
 	int i, cp[2];
+	struct sigaction sa;
 
 	if (child_state != CH_STOPPED && child_state != CH_DIED)
 		return;
@@ -390,6 +410,11 @@ mgt_launch_child(struct cli *cli)
 		setproctitle("Varnish-Chld %s", heritage.name);
 #endif
 
+		if (mgt_param.sigsegv_handler) {
+			sa.sa_sigaction = mgt_sigsegv_handler;
+			sa.sa_flags = SA_SIGINFO;
+			(void)sigaction(SIGSEGV, &sa, NULL);
+		}
 		(void)signal(SIGINT, SIG_DFL);
 		(void)signal(SIGTERM, SIG_DFL);
 
diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c
index 82ed98f..65a70b5 100644
--- a/bin/varnishd/mgt/mgt_param_tbl.c
+++ b/bin/varnishd/mgt/mgt_param_tbl.c
@@ -507,6 +507,11 @@ const struct parspec mgt_parspec[] = {
 		"on the cooloff list.\n",
 		WIZARD,
 		"180.0", "s" },
+	{ "sigsegv_handler", tweak_bool, &mgt_param.sigsegv_handler, 0, 0,
+		"Install a signal handler which tries to dump debug information "
+		"on segmentation faults.\n",
+		MUST_RESTART,
+		"off", "bool" },
 	{ "vcl_dir", tweak_string, &mgt_vcl_dir, 0, 0,
 		"Directory from which relative VCL filenames (vcl.load and "
 		"include) are opened.",
diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc
new file mode 100644
index 0000000..46469b7
--- /dev/null
+++ b/bin/varnishtest/tests/c00057.vtc
@@ -0,0 +1,19 @@
+varnishtest	"test sigsegv handler"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -cliok "param.set sigsegv_handler on" -vcl+backend {
+	C{
+#include <signal.h>
+}C
+	sub vcl_recv { C{ raise(SIGSEGV); }C }
+} -start
+
+client c1 {
+	txreq
+} -run
+
+varnish v1 -cliok "panic.show"



More information about the varnish-commit mailing list