squid-2414

Version:

2.7.S3

Bug link:

http://bugs.squid-cache.org/show_bug.cgi?id=2414

Symptom (failure):
Assertion failed.

How it is diagnosed:

We did not reproduce the failure so we only analyzed the source code and discussion threads.

Root Cause:

Squid forgot to clear a flag.

The assertion occurs when Squid is about to free a stored object in the function ‘fwdStateFree’, to free its forward state. The requirement for freeing this object is the object’s ENTRY_FWD_HDR_WAIT shouldn’t be set:

static void fwdStateFree(FwdState * fwdState) {

   StoreEntry *e = fwdState->entry;

   … …

   if (e->store_status == STORE_PENDING) {

        storeRequestFailed(e, fwdState->err);

        fwdState->err = NULL;

   }

   if (EBIT_TEST(e->flags, ENTRY_DEFER_READ))

        storeResetDefer(e);

   if (storePendingNClients(e) > 0)

        assert(!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT));

   … ...

   fwdServersFree(&fwdState->servers);

   requestUnlink(fwdState->request);

   fwdState->request = NULL;

   … …

}

For each stored object, there are a bunch of flags, and ENTRY_FWD_HDR_WAIT is one of them, indicating when we want to send this stored object to client, we need to wait a bit for Squid to verify that indeed the stored object is valid. In this case, however, when Squid is about to delete this object, there shouldn’t be any pending client.

It turns out when Squid forgot to clear this flag before the free:

--- src/store.c        26 Jun 2008 00:00:11 -0000        1.593

+++ src/store.c        18 Jul 2008 00:39:02 -0000

@@ -1378,6 +1378,7 @@ storeRequestFailed(StoreEntry * e, Error

        errorAppendEntry(e, err);

    } else {

        EBIT_SET(e->flags, ENTRY_ABORTED);

+        EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);

    }

    e->store_status = STORE_OK;

    mem->object_sz = mem->inmem_hi;

Is there any log message?:

Yes. The pattern is memory safety check.

Can Errlog anticipate this error msg?

Yes. Safety check! The assert was added to protect safety.