Commit 5df27a08 authored by Nils Goroll's avatar Nils Goroll

Add information about vcl object instances to the panic output

In the absence of a core dump, we do not have any information yet in the
panic output about vcl object instances, for example to find out which
object a priv belongs to when the instance address is used for
per-instance priv state.

To make this information available at the time of a panic, we add the
following:

* A struct vrt_ii (for instance info), of which a static gets
  filled in by VCC to contain the pointers to the C global variable
  instance pointers at VCC time

* A pointer to this struct from the VCL_conf to make it available to
  the varnishd worker

* dumps of the instance info for panics
parent 99ec7796
......@@ -44,6 +44,7 @@
#include "cache_vcl.h"
#include "vcli_serve.h"
#include "vtim.h"
#include "vcc_interface.h"
const struct vcltemp VCL_TEMP_INIT[1] = {{ .name = "init", .is_cold = 1 }};
const struct vcltemp VCL_TEMP_COLD[1] = {{ .name = "cold", .is_cold = 1 }};
......@@ -208,6 +209,7 @@ vcl_find(const char *name)
void
VCL_Panic(struct vsb *vsb, const char *nm, const struct vcl *vcl)
{
const struct vpi_ii *ii;
int i;
AN(vsb);
......@@ -233,6 +235,15 @@ VCL_Panic(struct vsb *vsb, const char *nm, const struct vcl *vcl)
for (i = 0; i < vcl->conf->nsrc; ++i)
VSB_printf(vsb, "\"%s\",\n", vcl->conf->srcname[i]);
VSB_indent(vsb, -2);
VSB_cat(vsb, "instances = {\n");
VSB_indent(vsb, 2);
ii = vcl->conf->instance_info;
while (ii != NULL && ii->p != NULL) {
VSB_printf(vsb, "\"%s\" = %p,\n", ii->name,
(const void *)*(const uintptr_t *)ii->p);
ii++;
}
VSB_indent(vsb, -2);
VSB_cat(vsb, "},\n");
}
VSB_indent(vsb, -2);
......
......@@ -26,6 +26,12 @@ server s1 {
varnish v1 -arg "-sdefault,1m" -vcl+backend {
import vtc;
import debug;
sub vcl_init {
new foo = debug.obj("foo");
new bar = debug.concat("bar");
}
sub vcl_backend_response {
if (beresp.http.panic == "fetch") {
......
......@@ -64,5 +64,11 @@ struct vrt_acl {
const char *name;
};
/* vmod object instance info */
struct vpi_ii {
const void * p;
const char * const name;
};
VCL_STRANDS VPI_BundleStrands(int, struct strands *, char const **,
const char *f, ...);
......@@ -656,6 +656,7 @@ struct VCL_conf {
const char **srcbody;
int nvmod;
const struct vpi_ii *instance_info;
vcl_event_f *event_vcl;
""")
......
......@@ -488,6 +488,7 @@ EmitStruct(const struct vcc *tl)
#define VCL_MET_MAC(l,u,t,b) \
Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n");
#include "tbl/vcl_returns.h"
Fc(tl, 0, "\t.instance_info = VGC_instance_info\n");
Fc(tl, 0, "};\n");
}
......@@ -711,6 +712,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
EmitInitFini(tl);
VCC_InstanceInfo(tl);
EmitStruct(tl);
VCC_XrefTable(tl);
......
......@@ -398,6 +398,7 @@ sym_act_f vcc_Act_New;
/* vcc_xref.c */
int vcc_CheckReferences(struct vcc *tl);
void VCC_InstanceInfo(struct vcc *tl);
void VCC_XrefTable(struct vcc *);
void vcc_AddCall(struct vcc *, struct token *, struct symbol *);
......
......@@ -317,6 +317,29 @@ vcc_xreftable_len(struct vcc *tl, const struct symbol *sym)
sym_type_len = len;
}
static void v_matchproto_(symwalk_f)
vcc_instance_info(struct vcc *tl, const struct symbol *sym)
{
CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
CHECK_OBJ_NOTNULL(sym->kind, KIND_MAGIC);
if (sym->kind != SYM_INSTANCE)
return;
AN(sym->rname);
Fc(tl, 0, "\t{ .p = &%s, .name = \"", sym->rname);
VCC_SymName(tl->fc, sym);
Fc(tl, 0, "\" },\n");
}
void
VCC_InstanceInfo(struct vcc *tl)
{
Fc(tl, 0, "\nconst struct vpi_ii VGC_instance_info[] = {\n");
VCC_WalkSymbols(tl, vcc_instance_info, SYM_NONE);
Fc(tl, 0, "\t{ .p = NULL, .name = \"\" }\n");
Fc(tl, 0, "};\n");
}
static void v_matchproto_(symwalk_f)
vcc_xreftable(struct vcc *tl, const struct symbol *sym)
{
......
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