Ben Laurie wrote:
>
> beatrous+@pitt.edu wrote:
> >
> > I've looked a little more closely at this. Gcache runs for a while and
> > then dies with a segmentation fault. If anyone can tell me how to crash it
> > on demand, I'll try to debug it.
>
> The formula I've been given is this (thanks to Matthias Suencks):
>
> procedure (two browser instances needed):
>
> * step 1: load a page (CGI-generated,if that matters) with a picture
> (static) in it
> with browser 1
> * important: now access the page with browser 2
>
> * now wait after the timeout, i.e. 6 minutes
> * reload the page with browser 1: the HTML page is re-loaded, but the
> image isnt't !!
> * gcache is crashed with the following message:
>
> EOF in saferead after 0 bytes
> httpsd: gcachecommon.c:54: ReadThing: Assertion `nRead == sizeof
> usLength' failed.
> connect: Connection refused
> httpsd: gcacheclient.c:37: OpenServer: Assertion `0' failed.
>
> final note: when I set the the gcache timeout to 10 seconds or so,
> it won't crash.
>
> My comments:
>
> 1. The fact it is CGI generated is almost certainly irrelevant, IMO.
>
> 2. I've just noticed that the timeout in the config file is completely
> ignored (it is hard coded to 15 seconds)! So the timings must be more
> important than the config settings. Yes, this will be fixed in 1.17.
>
> 3. I haven't tried this, I have no idea if it works at all.
>
> Cheers,
>
Well, it happened the same to me a couple of weeks ago, I think that the
cause isn't time related.
gcache.c accepts connections this way:
nFD=accept(nSocket,&saClient,&nLen);
HandleClient(nFD);
so if accept() fails, for example on EINTR, it goes on whith
HandleClient() and an invalid socket, it then calls ReadThing() and the
read() in saferead() returns 0 or -1, both values cause assert(nRead ==
sizeof usLength) to fail and gcache exit (it can also happen that the
user hits stop in the browser...).
Now, since gcacheclient.c exits on a failed connect() to gcache, and
gcache is now dead:
if(connect(nSocket,(struct sockaddr *)&saServer,sizeof saServer))
{
perror("connect");
assert(0);
}
this terminates each Apache process calling OpenServer(), the browser
gets "No data".
I went around the problem this way:
in gcache.c modified the call to accept():
if ((nFD=accept(nSocket,(struct sockaddr *)&saClient,&nLen)) < 0) {
if (errno == EINTR)
continue;
perror("accept");
exit(7);
}
in gcacheclient.c modified the call to connect():
if(connect(nSocket,(struct sockaddr *)&saServer,sizeof saServer))
{
perror("connect");
close(nSocket);
return -2;
}
and added this line in GlobalCacheAdd() after the call to OpenServer():
if (nFD < 0)
return;
and this in GlobalCacheGet() after the call to OpenServer():
if (nFD < 0)
return NULL;
Last, but not least, used -DNDEBUG in SSL_CFLAGS (src/Configuration) to
remove all the assert().
This way gcache is running fine, and if the Apache process isn't able to
connect it just goes on without sessions caching (so the server survives
to gcache's death).
Not sure this is the global solution, it worked for me in the last 2
weeks.
Ciao,
Stefano Ravaioli