r4060 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Sat May 9 17:54:08 CEST 2009


Author: phk
Date: 2009-05-09 17:54:08 +0200 (Sat, 09 May 2009)
New Revision: 4060

Modified:
   trunk/varnish-cache/bin/varnishd/cache_panic.c
   trunk/varnish-cache/bin/varnishd/common.h
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
Attempt to add a stack backtrace to the panic message.

Platform-breakage to be expected I pressume.

Apply gross hacks to POSIX-shortages, trying to get a result barely as
usable as what sensible operating systems have provided since at least
1985.



Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_panic.c	2009-05-09 15:51:08 UTC (rev 4059)
+++ trunk/varnish-cache/bin/varnishd/cache_panic.c	2009-05-09 15:54:08 UTC (rev 4060)
@@ -37,6 +37,11 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#ifndef HAVE_EXECINFO_H
+#include "compat/execinfo.h"
+#else
+#include <execinfo.h>
+#endif
 #include "cache.h"
 #include "cache_backend.h"
 #include "vcl.h"
@@ -249,6 +254,28 @@
 /*--------------------------------------------------------------------*/
 
 static void
+pan_backtrace(void)
+{
+	void *array[10];
+	size_t size;
+	size_t i;
+
+	size = backtrace (array, 10);
+	vsb_printf(vsp, "Backtrace:\n");
+	for (i = 0; i < size; i++) {
+		vsb_printf (vsp, "  ");
+		if (Symbol_Lookup(vsp, (uintptr_t)array[i]) < 0) {
+			char **strings;
+			strings = backtrace_symbols(&array[i], 1);
+			vsb_printf(vsp, "%p: %s", array[i], strings[0]);
+		}
+		vsb_printf (vsp, "\n");
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
 pan_ic(const char *func, const char *file, int line, const char *cond,
     int err, int xxx)
 {
@@ -264,7 +291,7 @@
 		break;
 	case 2:
 		vsb_printf(vsp,
-		    "Panic from VCL:\n%s\n", cond);
+		    "Panic from VCL:\n  %s\n", cond);
 		break;
 	case 1:
 		vsb_printf(vsp,
@@ -276,16 +303,19 @@
 	case 0:
 		vsb_printf(vsp,
 		    "Assert error in %s(), %s line %d:\n"
-		    "  Condition(%s) not true.",
+		    "  Condition(%s) not true.\n",
 		    func, file, line, cond);
 		break;
 	}
 	if (err)
-		vsb_printf(vsp, "  errno = %d (%s)", err, strerror(err));
+		vsb_printf(vsp, "errno = %d (%s)\n", err, strerror(err));
 
 	q = THR_GetName();
 	if (q != NULL)
-		vsb_printf(vsp, "  thread = (%s)", q);
+		vsb_printf(vsp, "thread = (%s)\n", q);
+
+	pan_backtrace();
+
 	if (!(params->diag_bitmap & 0x2000)) {
 		sp = THR_GetSession();
 		if (sp != NULL)

Modified: trunk/varnish-cache/bin/varnishd/common.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/common.h	2009-05-09 15:51:08 UTC (rev 4059)
+++ trunk/varnish-cache/bin/varnishd/common.h	2009-05-09 15:54:08 UTC (rev 4060)
@@ -44,6 +44,10 @@
 void VSL_MgtInit(const char *fn, unsigned size);
 extern struct varnish_stats *VSL_stats;
 
+/* varnishd.c */
+struct vsb;
+int Symbol_Lookup(struct vsb *vsb, uintptr_t ptr);
+
 #define TRUST_ME(ptr)	((void*)(uintptr_t)(ptr))
 
 /* Really belongs in mgt.h, but storage_file chokes on both */

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2009-05-09 15:51:08 UTC (rev 4059)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2009-05-09 15:54:08 UTC (rev 4060)
@@ -390,6 +390,90 @@
 	exit (2);
 }
 
+/*--------------------------------------------------------------------
+ * All praise POSIX!  Thanks to our glorious standards there are no
+ * standard way to get a back-trace of the stack, and even if we hack
+ * that together from spit and pieces of string, there is no way no
+ * standard way to translate a pointer to a symbol, which returns anything
+ * usable.  (See for instance FreeBSD PR-134391).
+ *
+ * Attempt to run nm(1) on our binary during startup, hoping it will
+ * give us a usable list of symbols.
+ */
+
+struct symbols {
+	uintptr_t		a;
+	char			*n;
+	VTAILQ_ENTRY(symbols)	list;
+};
+
+static VTAILQ_HEAD(,symbols) symbols = VTAILQ_HEAD_INITIALIZER(symbols);
+
+int
+Symbol_Lookup(struct vsb *vsb, uintptr_t ptr)
+{
+	struct symbols *s, *s0;
+
+	s0 = NULL;
+	VTAILQ_FOREACH(s, &symbols, list) {
+		if (s->a > ptr)
+			continue;
+		if (s0 != NULL && s->a < s0->a)
+			continue;
+		s0 = s;
+	}
+	if (s0 == NULL)
+		return (-1);
+	vsb_printf(vsb, "%p", (void *)ptr);
+	if (s0 != NULL)
+		vsb_printf(vsb, ": %s+%jx", s0->n, (uintmax_t)ptr - s0->a);
+	return (0);
+}
+
+static void
+Symbol_hack(const char *a0)
+{
+	char buf[BUFSIZ], *p, *e;
+	FILE *fi;
+	uintptr_t a;
+	struct symbols *s;
+
+	strcpy(buf, "nm -an ");
+	strcat(buf, a0);
+	fi = popen(buf, "r");
+	if (fi != NULL) {
+		while (fgets(buf, sizeof buf, fi)) {
+			if (buf[0] == ' ')
+				continue;
+			p = NULL;
+			a = strtoul(buf, &p, 16);
+			if (p == NULL)
+				continue;
+			if (a == 0)
+				continue;
+			if (*p++ != ' ')
+				continue;
+			p++;
+			if (*p++ != ' ')
+				continue;
+			if (*p <= ' ')
+				continue;
+			e = strchr(p, '\0');
+			AN(e);
+			while (e > p && isspace(e[-1]))
+				e--;
+			*e = '\0';
+			s = malloc(sizeof *s + strlen(p) + 1);
+			AN(s);
+			s->a = a;
+			s->n = (void*)(s + 1);
+			strcpy(s->n, p);
+			VTAILQ_INSERT_TAIL(&symbols, s, list);
+		}
+		pclose(fi);
+	}
+}
+
 /*--------------------------------------------------------------------*/
 
 int
@@ -419,6 +503,8 @@
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
 
+	Symbol_hack(argv[0]);
+
 	/* for ASSERT_MGT() */
 	mgt_pid = getpid();
 



More information about the varnish-commit mailing list