]> err.no Git - varnish/commitdiff
Reconstitute the dumping of sessions, objects &c &c, but now do it for
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sun, 20 Jul 2008 11:28:10 +0000 (11:28 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sun, 20 Jul 2008 11:28:10 +0000 (11:28 +0000)
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

index f773b30e815aa81e92b3d424d0abc18d736a3f3a..4bd54dc661e17b6fbca42b9098af69aa4c8ddd50 100644 (file)
 #include <stdlib.h>
 
 #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)