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