SES_Delete (#162)

Dag-Erling Smørgrav des at linpro.no
Tue Oct 23 15:26:12 CEST 2007


Here's a typical backtrace for that issue:

#0  0x0000000800d1048c in thr_kill () from /lib/libc.so.7
#1  0x0000000800d9a63b in abort () from /lib/libc.so.7
#2  0x000000080066dc7f in lbv_assert (func=Could not find the frame base for "lbv_assert".) at assert.c:58
#3  0x000000000041afb1 in SES_Delete (sp=0x2104b1a008) at cache_session.c:338
#4  0x0000000000408588 in vca_kev (kp=0x7fffff5fb340)
    at cache_acceptor_kqueue.c:112
#5  0x00000000004087e4 in vca_kqueue_main (arg=0x0)
    at cache_acceptor_kqueue.c:151
#6  0x0000000800a979a8 in pthread_getprio () from /lib/libthr.so.3
#7  0x0000000000000000 in ?? ()

Looking at the code, the assert in question is right at the top of
SES_Delete(), so we look at its caller instead.  The relevant code in
vca_kev() is:

109             } else if (kp->flags == EV_EOF) {
110                     VTAILQ_REMOVE(&sesshead, sp, list);
111                     vca_close_session(sp, "EOF");
112                     SES_Delete(sp);
113                     return;
114             }

We get to this part of the code when the remote end closes the
connection, triggering an EV_EOF kqueue event.

So what does vca_close_session() do?  Not much, really:

void
vca_close_session(struct sess *sp, const char *why)
{
	int i;

	VSL(SLT_SessionClose, sp->id, "%s", why);
	if (sp->fd >= 0) {
		i = close(sp->fd);
		assert(i == 0 || errno != EBADF);	/* XXX EINVAL seen */
	}
	sp->fd = -1;
}

What it certainly *doesn't* do in any way, shape or form is guarantee
that the session no longer has an object or VCL associated with it.
In other words, this assertion will fail every time the client closes
the connection before the completion of the current request.

Please tell me I've overlooked something...

DES
-- 
Dag-Erling Smørgrav
Senior Software Developer
Linpro AS - www.linpro.no



More information about the varnish-dev mailing list