Commit 677faa4e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4060 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 4b67d3dc
......@@ -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"
......@@ -248,6 +253,28 @@ pan_sess(const struct sess *sp)
/*--------------------------------------------------------------------*/
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 @@ pan_ic(const char *func, const char *file, int line, const char *cond,
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 @@ pan_ic(const char *func, const char *file, int line, const char *cond,
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)
......
......@@ -44,6 +44,10 @@ void VSL_Panic(int *len, char **ptr);
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 */
......
......@@ -390,6 +390,90 @@ cli_check(const struct cli *cli)
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 @@ main(int argc, char * const *argv)
setbuf(stdout, NULL);
setbuf(stderr, NULL);
Symbol_hack(argv[0]);
/* for ASSERT_MGT() */
mgt_pid = getpid();
......
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