Commit 778cbefc authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Use miniobj.h to catch pointer trouble


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@500 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 0c60cc3b
......@@ -13,6 +13,7 @@
#include "vcl_returns.h"
#include "common.h"
#include "miniobj.h"
#define MAX_IOVS 10
......@@ -39,6 +40,8 @@ enum step {
typedef void http_callback_f(void *, int bad);
struct http {
unsigned magic;
#define HTTP_MAGIC 0x6428b5c9
struct event ev;
http_callback_f *callback;
void *arg;
......@@ -61,6 +64,8 @@ struct http {
/*--------------------------------------------------------------------*/
struct worker {
unsigned magic;
#define WORKER_MAGIC 0x6391adcf
struct event_base *eb;
struct sbuf *sb;
struct objhead *nobjhead;
......@@ -76,6 +81,8 @@ struct worker {
};
struct workreq {
unsigned magic;
#define WORKREQ_MAGIC 0x5ccb4eb2
TAILQ_ENTRY(workreq) list;
struct sess *sess;
};
......@@ -85,6 +92,8 @@ struct workreq {
/* Backend Connection ------------------------------------------------*/
struct vbe_conn {
unsigned magic;
#define VBE_CONN_MAGIC 0x0c5e6592
TAILQ_ENTRY(vbe_conn) list;
struct vbc_mem *vbcm;
struct vbe *vbe;
......@@ -97,6 +106,8 @@ struct vbe_conn {
/* Storage -----------------------------------------------------------*/
struct storage {
unsigned magic;
#define STORAGE_MAGIC 0x1a4e51c0
TAILQ_ENTRY(storage) list;
unsigned char *ptr;
unsigned len;
......@@ -117,6 +128,8 @@ extern struct stevedore *stevedore;
/* -------------------------------------------------------------------*/
struct object {
unsigned magic;
#define OBJECT_MAGIC 0x32851d42
unsigned refcnt;
unsigned xid;
struct objhead *objhead;
......@@ -149,6 +162,8 @@ struct object {
};
struct objhead {
unsigned magic;
#define OBJHEAD_MAGIC 0x1b96615d
void *hashpriv;
pthread_mutex_t mtx;
......@@ -158,6 +173,8 @@ struct objhead {
/* -------------------------------------------------------------------*/
struct srcaddr {
unsigned magic;
#define SRCADDR_MAGIC 0x375111db
TAILQ_ENTRY(srcaddr) list;
unsigned nsess;
char addr[TCP_ADDRBUFSIZE];
......@@ -169,6 +186,8 @@ struct srcaddr {
};
struct sess {
unsigned magic;
#define SESS_MAGIC 0x2c2f9c5a
int fd;
unsigned xid;
......@@ -204,6 +223,8 @@ struct sess {
};
struct backend {
unsigned magic;
#define BACKEND_MAGIC 0x64c4c7c6
const char *vcl_name;
const char *hostname;
const char *portname;
......
......@@ -40,6 +40,8 @@
#include "cache.h"
struct vbc_mem {
unsigned magic;
#define VBC_MEM_MAGIC 0x2fd7af01
struct vbe_conn vbe;
struct http http;
char *http_hdr;
......@@ -48,6 +50,8 @@ struct vbc_mem {
/* A backend IP */
struct vbe {
unsigned magic;
#define VBE_MAGIC 0x079648f0
unsigned ip;
TAILQ_ENTRY(vbe) list;
TAILQ_HEAD(,vbe_conn) fconn;
......@@ -78,7 +82,9 @@ vbe_new_conn(void)
1);
if (vbcm == NULL)
return (NULL);
vbcm->magic = VBC_MEM_MAGIC;
VSL_stats->n_vbe_conn++;
vbcm->vbe.magic = VBE_CONN_MAGIC;
vbcm->vbe.vbcm = vbcm;
vbcm->vbe.http = &vbcm->http;
http_Init(&vbcm->http, (void *)(vbcm + 1));
......@@ -89,6 +95,8 @@ static void
vbe_delete_conn(struct vbe_conn *vb)
{
CHECK_OBJ_NOTNULL(vb, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(vb->vbcm, VBC_MEM_MAGIC);
VSL_stats->n_vbe_conn--;
free(vb->vbcm);
}
......@@ -299,6 +307,7 @@ VBE_GetFd(struct backend *bp, unsigned xid)
struct vbe *vp;
struct vbe_conn *vc;
CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
AZ(pthread_mutex_lock(&vbemtx));
vp = bp->vbe;
if (vp == NULL) {
......
......@@ -566,8 +566,21 @@ void
CNT_Session(struct sess *sp)
{
int done;
struct worker *w;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
w = sp->wrk;
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
for (done = 0; !done; ) {
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
if (sp->obj != NULL)
CHECK_OBJ(sp->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
switch (sp->step) {
#define STEP(l,u) \
case STP_##u: \
......@@ -578,6 +591,10 @@ CNT_Session(struct sess *sp)
#undef STEP
default: INCOMPL();
}
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
}
}
......
......@@ -6,6 +6,7 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "libvarnish.h"
#include "shmlog.h"
......@@ -56,6 +57,7 @@ exp_hangman(void *arg)
t = time(NULL);
AZ(pthread_mutex_lock(&exp_mtx));
TAILQ_FOREACH(o, &exp_deathrow, deathrow) {
CHECK_OBJ(o, OBJECT_MAGIC);
if (o->ttl >= t) {
o = NULL;
break;
......@@ -94,14 +96,17 @@ exp_prefetch(void *arg)
{
struct object *o;
time_t t;
struct sess sp;
struct sess *sp;
(void)arg;
sp = SES_New(NULL, 0);
while (1) {
t = time(NULL);
AZ(pthread_mutex_lock(&exp_mtx));
o = binheap_root(exp_heap);
if (o != NULL)
CHECK_OBJ(o, OBJECT_MAGIC);
if (o == NULL || o->ttl > t + expearly) {
AZ(pthread_mutex_unlock(&exp_mtx));
AZ(sleep(1));
......@@ -111,18 +116,18 @@ exp_prefetch(void *arg)
AZ(pthread_mutex_unlock(&exp_mtx));
VSL(SLT_ExpPick, 0, "%u", o->xid);
sp.vcl = VCL_Get();
sp.obj = o;
VCL_timeout_method(&sp);
VCL_Rel(sp.vcl);
sp->vcl = VCL_Get();
sp->obj = o;
VCL_timeout_method(sp);
VCL_Rel(sp->vcl);
if (sp.handling == VCL_RET_DISCARD) {
if (sp->handling == VCL_RET_DISCARD) {
AZ(pthread_mutex_lock(&exp_mtx));
TAILQ_INSERT_TAIL(&exp_deathrow, o, deathrow);
AZ(pthread_mutex_unlock(&exp_mtx));
continue;
}
assert(sp.handling == VCL_RET_DISCARD);
assert(sp->handling == VCL_RET_DISCARD);
}
}
......
......@@ -48,6 +48,9 @@ HSH_Lookup(struct sess *sp)
struct object *o;
char *c;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
assert(hash != NULL);
w = sp->wrk;
h = sp->http;
......@@ -56,29 +59,36 @@ HSH_Lookup(struct sess *sp)
if (w->nobjhead == NULL) {
w->nobjhead = calloc(sizeof *w->nobjhead, 1);
assert(w->nobjhead != NULL);
w->nobjhead->magic = OBJHEAD_MAGIC;
TAILQ_INIT(&w->nobjhead->objects);
AZ(pthread_mutex_init(&w->nobjhead->mtx, NULL));
VSL_stats->n_objecthead++;
}
} else
CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
if (w->nobj == NULL) {
w->nobj = calloc(sizeof *w->nobj, 1);
assert(w->nobj != NULL);
w->nobj->magic = OBJECT_MAGIC;
w->nobj->busy = 1;
w->nobj->refcnt = 1;
TAILQ_INIT(&w->nobj->store);
TAILQ_INIT(&w->nobj->waitinglist);
VSL_stats->n_object++;
}
} else
CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
if (!http_GetHdr(h, "Host", &c))
c = h->url;
if (sp->obj != NULL) {
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
o = sp->obj;
oh = o->objhead;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
AZ(pthread_mutex_lock(&oh->mtx));
goto were_back;
}
oh = hash->lookup(h->url, c, w->nobjhead);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oh == w->nobjhead)
w->nobjhead = NULL;
AZ(pthread_mutex_lock(&oh->mtx));
......
......@@ -23,6 +23,7 @@ http_Init(struct http *hp, void *space)
char *sp = space;
memset(hp, 0, sizeof *hp);
hp->magic = HTTP_MAGIC;
hp->hdr = (void *)sp;
sp += heritage.mem_http_headers * sizeof hp->hdr;
hp->s = sp;
......
......@@ -35,6 +35,7 @@ wrk_thread(void *priv)
w = &ww;
memset(w, 0, sizeof *w);
w->magic = WORKER_MAGIC;
AZ(pthread_cond_init(&w->cv, NULL));
......@@ -54,6 +55,11 @@ wrk_thread(void *priv)
}
TAILQ_INSERT_HEAD(&wrk_head, w, list);
while (1) {
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
wrq = TAILQ_FIRST(&wrk_reqhead);
if (wrq != NULL) {
VSL_stats->n_wrk_busy++;
......@@ -62,6 +68,7 @@ wrk_thread(void *priv)
AZ(pthread_mutex_unlock(&wrk_mtx));
assert(wrq->sess != NULL);
wrq->sess->wrk = w;
CHECK_OBJ_NOTNULL(wrq->sess, SESS_MAGIC);
CNT_Session(wrq->sess);
AZ(pthread_mutex_lock(&wrk_mtx));
VSL_stats->n_wrk_busy--;
......@@ -71,12 +78,20 @@ wrk_thread(void *priv)
wrk_overflow--;
continue;
}
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
/* If we are a reserved thread we don't die */
if (priv != NULL) {
AZ(pthread_cond_wait(&w->cv, &wrk_mtx));
continue;
}
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
/* If we are a dynamic thread, time out and die */
AZ(clock_gettime(CLOCK_REALTIME, &ts));
......@@ -91,6 +106,10 @@ wrk_thread(void *priv)
AZ(pthread_cond_destroy(&w->cv));
return (NULL);
}
if (w->nobj != NULL)
CHECK_OBJ(w->nobj, OBJECT_MAGIC);
if (w->nobjhead != NULL)
CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
}
}
......
......@@ -27,6 +27,9 @@
/*--------------------------------------------------------------------*/
struct sessmem {
unsigned magic;
#define SESSMEM_MAGIC 0x555859c5
struct sess sess;
struct http http;
char *http_hdr;
......@@ -156,7 +159,9 @@ SES_New(struct sockaddr *addr, unsigned len)
1);
if (sm == NULL)
return (NULL);
sm->magic = SESSMEM_MAGIC;
VSL_stats->n_sess++;
sm->sess.magic = SESS_MAGIC;
sm->sess.mem = sm;
sm->sess.http = &sm->http;
http_Init(&sm->http, (void *)(sm + 1));
......@@ -167,8 +172,10 @@ void
SES_Delete(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL_stats->n_sess--;
SES_RelSrcAddr(sp);
CHECK_OBJ_NOTNULL(sp->mem, SESSMEM_MAGIC);
free(sp->mem);
}
......
......@@ -20,7 +20,7 @@ void
VRT_error(struct sess *sp, unsigned err, const char *str)
{
(void)sp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL(SLT_Debug, 0, "VCL_error(%u, %s)", err, str);
}
......@@ -30,6 +30,7 @@ void
VRT_count(struct sess *sp, unsigned u)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VSL(SLT_VCL_trace, sp->fd, "%u %d.%d", u,
sp->vcl->ref[u].line,
sp->vcl->ref[u].pos);
......@@ -42,6 +43,7 @@ VRT_GetHdr(struct sess *sp, const char *n)
{
char *p;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp != NULL);
assert(sp->http != NULL);
if (!http_GetHdr(sp->http, n, &p))
......@@ -55,6 +57,7 @@ char *
VRT_GetReq(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp != NULL);
assert(sp->http != NULL);
return (sp->http->req);
......@@ -66,6 +69,7 @@ void
VRT_handling(struct sess *sp, unsigned hand)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(!(hand & (hand -1))); /* must be power of two */
sp->handling = hand;
}
......@@ -73,30 +77,35 @@ VRT_handling(struct sess *sp, unsigned hand)
int
VRT_obj_valid(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp->obj->valid);
}
int
VRT_obj_cacheable(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp->obj->cacheable);
}
void
VRT_set_backend_hostname(struct backend *be, const char *h)
{
CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->hostname = h;
}
void
VRT_set_backend_portname(struct backend *be, const char *p)
{
CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->portname = p;
}
void
VRT_set_backend_name(struct backend *be, const char *p)
{
CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
be->vcl_name = p;
}
......@@ -110,5 +119,6 @@ VRT_alloc_backends(struct VCL_conf *cp)
for (i = 0; i < cp->nbackend; i++) {
cp->backend[i] = calloc(sizeof *cp->backend[i], 1);
assert(cp->backend[i] != NULL);
cp->backend[i]->magic = BACKEND_MAGIC;
}
}
......@@ -16,10 +16,12 @@
/*--------------------------------------------------------------------*/
struct hcl_entry {
unsigned magic;
#define HCL_ENTRY_MAGIC 0x0ba707bf
TAILQ_ENTRY(hcl_entry) list;
char *key1;
char *key2;
struct objhead *obj;
struct objhead *oh;
unsigned refcnt;
unsigned hash;
unsigned mtx;
......@@ -98,7 +100,7 @@ hcl_start(void)
*/
static struct objhead *
hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
hcl_lookup(const char *key1, const char *key2, struct objhead *noh)
{
struct hcl_entry *he, *he2;
MD5_CTX c;
......@@ -106,6 +108,7 @@ hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
unsigned u1, u2;
int i;
CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC);
MD5Init(&c);
MD5Update(&c, key1, strlen(key1));
MD5Update(&c, "", 1);
......@@ -118,6 +121,7 @@ hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
AZ(pthread_mutex_lock(&hcl_mutex[u2]));
TAILQ_FOREACH(he, &hcl_head[u1], list) {
CHECK_OBJ_NOTNULL(he, HCL_ENTRY_MAGIC);
i = strcmp(key1, he->key1);
if (i < 0)
continue;
......@@ -129,18 +133,19 @@ hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
if (i > 0)
break;
he->refcnt++;
nobj = he->obj;
nobj->hashpriv = he;
noh = he->oh;
noh->hashpriv = he;
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
return (nobj);
return (noh);
}
if (nobj == NULL) {
if (noh == NULL) {
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
return (NULL);
}
he2 = calloc(sizeof *he2, 1);
assert(he2 != NULL);
he2->obj = nobj;
he2->magic = HCL_ENTRY_MAGIC;
he2->oh = noh;
he2->refcnt = 1;
he2->hash = u1;
he2->mtx = u2;
......@@ -148,13 +153,13 @@ hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
assert(he2->key1 != NULL);
he2->key2 = strdup(key2);
assert(he2->key2 != NULL);
nobj->hashpriv = he2;
noh->hashpriv = he2;
if (he != NULL)
TAILQ_INSERT_BEFORE(he, he2, list);
else
TAILQ_INSERT_TAIL(&hcl_head[u1], he2, list);
AZ(pthread_mutex_unlock(&hcl_mutex[u2]));
return (nobj);
return (noh);
}
/*--------------------------------------------------------------------
......@@ -162,14 +167,14 @@ hcl_lookup(const char *key1, const char *key2, struct objhead *nobj)
*/
static int
hcl_deref(struct objhead *obj)
hcl_deref(struct objhead *oh)
{
struct hcl_entry *he;
int ret;
unsigned mtx;
assert(obj->hashpriv != NULL);
he = obj->hashpriv;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
CAST_OBJ_NOTNULL(he, oh->hashpriv, HCL_ENTRY_MAGIC);
mtx = he->mtx;
AZ(pthread_mutex_lock(&hcl_mutex[mtx]));
if (--he->refcnt == 0) {
......
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