From 4d668d30c57ad8ce2f790b291a4c98335f88140e Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 20 Jul 2008 11:28:10 +0000 Subject: [PATCH] Reconstitute the dumping of sessions, objects &c &c, but now do it for all asserts from a thread with a registered session. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2975 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_panic.c | 262 +++++++++++------------ 1 file changed, 125 insertions(+), 137 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_panic.c b/varnish-cache/bin/varnishd/cache_panic.c index f773b30e..4bd54dc6 100644 --- a/varnish-cache/bin/varnishd/cache_panic.c +++ b/varnish-cache/bin/varnishd/cache_panic.c @@ -37,211 +37,198 @@ #include #include "cache.h" +#include "cache_backend.h" #include "vcl.h" -#ifndef WITHOUT_ASSERTS - /* - * The panic string is constructed in memory, then printed to stderr. It - * can be extracted post-mortem from a core dump using gdb: + * The panic string is constructed in memory, then copied to the + * shared memory. + * + * It can be extracted post-mortem from a core dump using gdb: * * (gdb) printf "%s", panicstr */ + char panicstr[65536]; static struct vsb vsps, *vsp; -static char *pstr = panicstr; - -#define fp(...) \ - do { \ - pstr += snprintf(pstr, \ - (panicstr + sizeof panicstr) - pstr, \ - __VA_ARGS__); \ - } while (0) - -#define vfp(fmt, ap) \ - do { \ - pstr += vsnprintf(pstr, \ - (panicstr + sizeof panicstr) - pstr, \ - (fmt), (ap)); \ - } while (0) - -/* step names */ -static const char *steps[] = { -#define STEP(l, u) [STP_##u] = "STP_" #u, -#include "steps.h" -#undef STEP -}; -static int nsteps = sizeof steps / sizeof *steps; +#if 0 + +void +panic(const char *file, int line, const char *func, + const struct sess *sp, const char *fmt, ...) +{ + va_list ap; + + vsb_printf(vsp, "panic in %s() at %s:%d\n", func, file, line); + va_start(ap, fmt); + vvsb_printf(vsp, fmt, ap); + va_end(ap); + + if (VALID_OBJ(sp, SESS_MAGIC)) + dump_sess(sp); + + (void)fputs(panicstr, stderr); + + /* I wish there was a way to flush the log buffers... */ + (void)signal(SIGABRT, SIG_DFL); +#ifdef HAVE_ABORT2 + { + void *arg[1]; + char *p; + + for (p = panicstr; *p; p++) + if (*p == '\n') + *p = ' '; + arg[0] = panicstr; + abort2(panicstr, 1, arg); + } +#endif + (void)raise(SIGABRT); +} + +#endif + +/*--------------------------------------------------------------------*/ -/* dump a struct VCL_conf */ static void -dump_vcl(const struct VCL_conf *vcl) +pan_backend(const struct backend *be) { - int i; - fp(" vcl = {\n"); - fp(" srcname = {\n"); - for (i = 0; i < vcl->nsrc; ++i) - fp(" \"%s\",\n", vcl->srcname[i]); - fp(" },\n"); - fp(" },\n"); + vsb_printf(vsp, " backend = %p {\n", be); + vsb_printf(vsp, " vcl_name = \"%s\",\n", be->vcl_name); + vsb_printf(vsp, " },\n"); } -/* dump a struct storage */ +/*--------------------------------------------------------------------*/ + static void -dump_storage(const struct storage *st) +pan_storage(const struct storage *st) { int i, j; #define MAX_BYTES (4*16) #define show(ch) (((ch) > 31 && (ch) < 127) ? (ch) : '.') - fp(" %u {\n", st->len); + vsb_printf(vsp, " %u {\n", st->len); for (i = 0; i < MAX_BYTES && i < st->len; i += 16) { - fp(" "); + vsb_printf(vsp, " "); for (j = 0; j < 16; ++j) { if (i + j < st->len) - fp("%02x ", st->ptr[i + j]); + vsb_printf(vsp, "%02x ", st->ptr[i + j]); else - fp(" "); + vsb_printf(vsp, " "); } - fp("|"); + vsb_printf(vsp, "|"); for (j = 0; j < 16; ++j) if (i + j < st->len) - fp("%c", show(st->ptr[i + j])); - fp("|\n"); + vsb_printf(vsp, "%c", show(st->ptr[i + j])); + vsb_printf(vsp, "|\n"); } if (st->len > MAX_BYTES) - fp(" [%u more]\n", st->len - MAX_BYTES); - fp(" },\n"); + vsb_printf(vsp, " [%u more]\n", st->len - MAX_BYTES); + vsb_printf(vsp, " },\n"); #undef show #undef MAX_BYTES } -/* dump a struct http */ +/*--------------------------------------------------------------------*/ + static void -dump_http(const struct http *h) +pan_http(const struct http *h) { int i; - fp(" http = {\n"); + vsb_printf(vsp, " http = {\n"); if (h->nhd > HTTP_HDR_FIRST) { - fp(" hd = {\n"); + vsb_printf(vsp, " hd = {\n"); for (i = HTTP_HDR_FIRST; i < h->nhd; ++i) - fp(" \"%.*s\",\n", + vsb_printf(vsp, " \"%.*s\",\n", (int)(h->hd[i].e - h->hd[i].b), h->hd[i].b); - fp(" },\n"); + vsb_printf(vsp, " },\n"); } - fp(" },\n"); + vsb_printf(vsp, " },\n"); } -/* dump a struct object */ + +/*--------------------------------------------------------------------*/ + static void -dump_object(const struct object *o) +pan_object(const struct object *o) { const struct storage *st; - fp(" obj = %p {\n", o); - fp(" refcnt = %u, xid = %u,\n", o->refcnt, o->xid); - dump_http(o->http); - fp(" len = %u,\n", o->len); - fp(" store = {\n"); - VTAILQ_FOREACH(st, &o->store, list) { - dump_storage(st); - } - fp(" },\n"); - fp(" },\n"); + vsb_printf(vsp, " obj = %p {\n", o); + vsb_printf(vsp, " refcnt = %u, xid = %u,\n", o->refcnt, o->xid); + pan_http(o->http); + vsb_printf(vsp, " len = %u,\n", o->len); + vsb_printf(vsp, " store = {\n"); + VTAILQ_FOREACH(st, &o->store, list) + pan_storage(st); + vsb_printf(vsp, " },\n"); + vsb_printf(vsp, " },\n"); } -#if 0 -/* dump a struct backend */ +/*--------------------------------------------------------------------*/ + static void -dump_backend(const struct backend *be) +pan_vcl(const struct VCL_conf *vcl) { + int i; - fp(" backend = %p {\n", be); - fp(" vcl_name = \"%s\",\n", - be->vcl_name ? be->vcl_name : "(null)"); - fp(" },\n"); + vsb_printf(vsp, " vcl = {\n"); + vsb_printf(vsp, " srcname = {\n"); + for (i = 0; i < vcl->nsrc; ++i) + vsb_printf(vsp, " \"%s\",\n", vcl->srcname[i]); + vsb_printf(vsp, " },\n"); + vsb_printf(vsp, " },\n"); } -#endif -/* dump a struct sess */ +/*--------------------------------------------------------------------*/ + static void -dump_sess(const struct sess *sp) +pan_sess(const struct sess *sp) { -#if 0 - const struct backend *be = sp->backend; -#endif - const struct object *obj = sp->obj; - const struct VCL_conf *vcl = sp->vcl; + const char *stp; - fp("sp = %p {\n", sp); - fp(" fd = %d, id = %d, xid = %u,\n", sp->fd, sp->id, sp->xid); - fp(" client = %s:%s,\n", + vsb_printf(vsp, "sp = %p {\n", sp); + vsb_printf(vsp, + " fd = %d, id = %d, xid = %u,\n", sp->fd, sp->id, sp->xid); + vsb_printf(vsp, " client = %s:%s,\n", sp->addr ? sp->addr : "?.?.?.?", sp->port ? sp->port : "?"); - if (sp->step < nsteps) - fp(" step = %s,\n", steps[sp->step]); + switch (sp->step) { +/*lint -save -e525 */ +#define STEP(l, u) case STP_##u: stp = "STP_" #u; break; +#include "steps.h" +#undef STEP +/*lint -restore */ + default: stp = NULL; + } + if (stp != NULL) + vsb_printf(vsp, " step = %s,\n", stp); else - fp(" step = %d,\n", sp->step); + vsb_printf(vsp, " step = 0x%x,\n", sp->step); if (sp->err_code) - fp(" err_code = %d, err_reason = %s,\n", sp->err_code, + vsb_printf(vsp, + " err_code = %d, err_reason = %s,\n", sp->err_code, sp->err_reason ? sp->err_reason : "(null)"); - if (VALID_OBJ(vcl, VCL_CONF_MAGIC)) - dump_vcl(vcl); - -#if 0 - if (VALID_OBJ(be, BACKEND_MAGIC)) - dump_backend(be); - INCOMPL(): -#endif - - if (VALID_OBJ(obj, OBJECT_MAGIC)) - dump_object(obj); - - fp("},\n"); -} - -/* report as much information as we can before we croak */ -void -panic(const char *file, int line, const char *func, - const struct sess *sp, const char *fmt, ...) -{ - va_list ap; - - fp("panic in %s() at %s:%d\n", func, file, line); - va_start(ap, fmt); - vfp(fmt, ap); - va_end(ap); + if (VALID_OBJ(sp->vcl, VCL_CONF_MAGIC)) + pan_vcl(sp->vcl); - if (VALID_OBJ(sp, SESS_MAGIC)) - dump_sess(sp); + if (VALID_OBJ(sp->backend, BACKEND_MAGIC)) + pan_backend(sp->backend); - (void)fputs(panicstr, stderr); + if (VALID_OBJ(sp->obj, OBJECT_MAGIC)) + pan_object(sp->obj); - /* I wish there was a way to flush the log buffers... */ - (void)signal(SIGABRT, SIG_DFL); -#ifdef HAVE_ABORT2 - { - void *arg[1]; - char *p; - - for (p = panicstr; *p; p++) - if (*p == '\n') - *p = ' '; - arg[0] = panicstr; - abort2(panicstr, 1, arg); - } -#endif - (void)raise(SIGABRT); + vsb_printf(vsp, "},\n"); } -#endif +/*--------------------------------------------------------------------*/ static void pan_ic(const char *func, const char *file, int line, const char *cond, int err, int xxx) @@ -269,16 +256,17 @@ pan_ic(const char *func, const char *file, int line, const char *cond, int err, if (q != NULL) vsb_printf(vsp, " thread = (%s)", q); sp = THR_GetSession(); - if (sp != NULL) - vsb_printf(vsp, " sess = (%p)", sp); + if (sp != NULL) + pan_sess(sp); vsb_printf(vsp, "\n"); VSL_Panic(&l, &p); - if (l < vsb_len(vsp)) - l = vsb_len(vsp); + if (l < sizeof(panicstr)) + l = sizeof(panicstr); memcpy(p, panicstr, l); abort(); } +/*--------------------------------------------------------------------*/ void PAN_Init(void) -- 2.39.5