static void pan_req(const struct req *req) { const char *stp; VSB_printf(pan_vsp, "req = %p {\n", req); VSB_printf(pan_vsp, " sp = %p, vxid = %u,", req->sp, VXID(req->vsl->wid)); switch (req->req_step) { #define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break; #include "tbl/steps.h" #undef REQ_STEP default: stp = NULL; } if (stp != NULL) VSB_printf(pan_vsp, " step = %s,\n", stp); else VSB_printf(pan_vsp, " step = 0x%x,\n", req->req_step); VSB_printf(pan_vsp, " req_body = %s,\n", reqbody_status_2str(req->req_body_status)); if (req->err_code) VSB_printf(pan_vsp, " err_code = %d, err_reason = %s,\n", req->err_code, req->err_reason ? req->err_reason : "(null)"); VSB_printf(pan_vsp, " restarts = %d, esi_level = %d\n", req->restarts, req->esi_level); if (req->sp != NULL) pan_sess(req->sp); if (req->wrk != NULL) pan_wrk(req->wrk); pan_ws(req->ws, 2); pan_http("req", req->http, 2); if (req->resp->ws != NULL) pan_http("resp", req->resp, 2); if (VALID_OBJ(req->vcl, VCL_CONF_MAGIC)) pan_vcl(req->vcl); if (req->objcore != NULL) { pan_objcore("REQ", req->objcore); if (req->objcore->busyobj != NULL) pan_busyobj(req->objcore->busyobj); } VSB_printf(pan_vsp, "},\n"); }
static void pan_sess(const struct sess *sp) { const char *stp, *hand; VSB_printf(pan_vsp, "sp = %p {\n", sp); VSB_printf(pan_vsp, " fd = %d, id = %u, xid = %u,\n", sp->fd, sp->vsl_id & VSL_IDENTMASK, sp->req->xid); VSB_printf(pan_vsp, " client = %s %s,\n", sp->addr ? sp->addr : "?.?.?.?", sp->port ? sp->port : "?"); switch (sp->step) { #define STEP(l, u, arg) case STP_##u: stp = "STP_" #u; break; #include "tbl/steps.h" #undef STEP default: stp = NULL; } hand = VCL_Return_Name(sp->req->handling); if (stp != NULL) VSB_printf(pan_vsp, " step = %s,\n", stp); else VSB_printf(pan_vsp, " step = 0x%x,\n", sp->step); if (hand != NULL) VSB_printf(pan_vsp, " handling = %s,\n", hand); else VSB_printf(pan_vsp, " handling = 0x%x,\n", sp->req->handling); if (sp->req->err_code) VSB_printf(pan_vsp, " err_code = %d, err_reason = %s,\n", sp->req->err_code, sp->req->err_reason ? sp->req->err_reason : "(null)"); VSB_printf(pan_vsp, " restarts = %d, esi_level = %d\n", sp->req->restarts, sp->req->esi_level); if (sp->wrk->busyobj != NULL) pan_busyobj(sp->wrk->busyobj); pan_ws(sp->req->ws, 2); pan_http("req", sp->req->http, 2); if (sp->req->resp->ws != NULL) pan_http("resp", sp->req->resp, 4); if (sp->wrk != NULL) pan_wrk(sp->wrk); if (VALID_OBJ(sp->req->vcl, VCL_CONF_MAGIC)) pan_vcl(sp->req->vcl); if (VALID_OBJ(sp->req->obj, OBJECT_MAGIC)) pan_object(sp->req->obj); VSB_printf(pan_vsp, "},\n"); }
pan_ic(const char *func, const char *file, int line, const char *cond, int err, enum vas_e kind) { const char *q; struct req *req; struct busyobj *bo; AZ(pthread_mutex_lock(&panicstr_mtx)); /* Won't be released, we're going to die anyway */ switch(kind) { case VAS_WRONG: VSB_printf(pan_vsp, "Wrong turn at %s:%d:\n%s\n", file, line, cond); break; case VAS_VCL: VSB_printf(pan_vsp, "Panic from VCL:\n %s\n", cond); break; case VAS_MISSING: VSB_printf(pan_vsp, "Missing errorhandling code in %s(), %s line %d:\n" " Condition(%s) not true.", func, file, line, cond); break; case VAS_INCOMPLETE: VSB_printf(pan_vsp, "Incomplete code in %s(), %s line %d:\n", func, file, line); break; default: case VAS_ASSERT: VSB_printf(pan_vsp, "Assert error in %s(), %s line %d:\n" " Condition(%s) not true.\n", func, file, line, cond); break; } if (err) VSB_printf(pan_vsp, "errno = %d (%s)\n", err, strerror(err)); q = THR_GetName(); if (q != NULL) VSB_printf(pan_vsp, "thread = (%s)\n", q); VSB_printf(pan_vsp, "ident = %s,%s\n", VSB_data(vident) + 1, WAIT_GetName()); pan_backtrace(); if (!FEATURE(FEATURE_SHORT_PANIC)) { req = THR_GetRequest(); if (req != NULL) { pan_req(req); VSL_Flush(req->vsl, 0); } bo = THR_GetBusyobj(); if (bo != NULL) { pan_busyobj(bo); VSL_Flush(bo->vsl, 0); } } VSB_printf(pan_vsp, "\n"); VSB_bcat(pan_vsp, "", 1); /* NUL termination */ if (FEATURE(FEATURE_NO_COREDUMP)) exit(4); else abort(); }
pan_ic(const char *func, const char *file, int line, const char *cond, enum vas_e kind) { const char *q; struct req *req; struct busyobj *bo; struct sigaction sa; int err = errno; AZ(pthread_mutex_lock(&panicstr_mtx)); /* Won't be released, we're going to die anyway */ /* * should we trigger a SIGSEGV while handling a panic, our sigsegv * handler would hide the panic, so we need to reset the handler to * default */ memset(&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; (void)sigaction(SIGSEGV, &sa, NULL); /* Set SIGABRT back to default so the final abort() has the desired effect */ (void)sigaction(SIGABRT, &sa, NULL); switch(kind) { case VAS_WRONG: VSB_printf(pan_vsb, "Wrong turn at %s:%d:\n%s\n", file, line, cond); break; case VAS_VCL: VSB_printf(pan_vsb, "Panic from VCL:\n %s\n", cond); break; case VAS_MISSING: VSB_printf(pan_vsb, "Missing errorhandling code in %s(), %s line %d:\n" " Condition(%s) not true.", func, file, line, cond); break; case VAS_INCOMPLETE: VSB_printf(pan_vsb, "Incomplete code in %s(), %s line %d:\n", func, file, line); break; default: case VAS_ASSERT: VSB_printf(pan_vsb, "Assert error in %s(), %s line %d:\n" " Condition(%s) not true.\n", func, file, line, cond); break; } if (err) VSB_printf(pan_vsb, "errno = %d (%s)\n", err, strerror(err)); q = THR_GetName(); if (q != NULL) VSB_printf(pan_vsb, "thread = (%s)\n", q); VSB_printf(pan_vsb, "version = %s\n", VCS_version); VSB_printf(pan_vsb, "ident = %s,%s\n", VSB_data(vident) + 1, Waiter_GetName()); pan_backtrace(pan_vsb); if (!FEATURE(FEATURE_SHORT_PANIC)) { req = THR_GetRequest(); if (req != NULL) { pan_req(pan_vsb, req); VSL_Flush(req->vsl, 0); } bo = THR_GetBusyobj(); if (bo != NULL) { pan_busyobj(pan_vsb, bo); VSL_Flush(bo->vsl, 0); } } VSB_printf(pan_vsb, "\n"); VSB_bcat(pan_vsb, "", 1); /* NUL termination */ if (FEATURE(FEATURE_NO_COREDUMP)) exit(4); else abort(); }
static void pan_req(struct vsb *vsb, const struct req *req) { const char *stp; VSB_printf(vsb, "req = %p {\n", req); VSB_indent(vsb, 2); VSB_printf(vsb, "vxid = %u, ", VXID(req->vsl->wid)); switch (req->req_step) { #define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break; #include "tbl/steps.h" #undef REQ_STEP default: stp = NULL; } if (stp != NULL) VSB_printf(vsb, "step = %s,\n", stp); else VSB_printf(vsb, "step = 0x%x,\n", req->req_step); VSB_printf(vsb, "req_body = %s,\n", reqbody_status_2str(req->req_body_status)); if (req->err_code) VSB_printf(vsb, "err_code = %d, err_reason = %s,\n", req->err_code, req->err_reason ? req->err_reason : "(null)"); VSB_printf(vsb, "restarts = %d, esi_level = %d,\n", req->restarts, req->esi_level); if (req->sp != NULL) pan_sess(vsb, req->sp); if (req->wrk != NULL) pan_wrk(vsb, req->wrk); pan_ws(vsb, req->ws); if (VALID_OBJ(req->htc, HTTP_CONN_MAGIC)) pan_htc(vsb, req->htc); pan_http(vsb, "req", req->http); if (req->resp->ws != NULL) pan_http(vsb, "resp", req->resp); VCL_Panic(vsb, req->vcl); if (req->objcore != NULL) { pan_objcore(vsb, "REQ", req->objcore); if (req->objcore->busyobj != NULL) pan_busyobj(vsb, req->objcore->busyobj); } VSB_printf(vsb, "flags = {\n"); VSB_indent(vsb, 2); #define REQ_FLAG(l, r, w, d) if(req->l) VSB_printf(vsb, #l ",\n"); #include "tbl/req_flags.h" #undef REQ_FLAG VSB_indent(vsb, -2); VSB_printf(vsb, "},\n"); VSB_indent(vsb, -2); VSB_printf(vsb, "},\n"); }