From: robertc <> Date: Fri, 25 Oct 2002 09:13:51 +0000 (+0000) Subject: cbdata history for cbdata debug mode X-Git-Tag: SQUID_3_0_PRE1~568 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e48ed43391a35b15066e876ca69755a5582dc26b;p=thirdparty%2Fsquid.git cbdata history for cbdata debug mode --- diff --git a/include/Array.h b/include/Array.h index 4502a74811..f7d75ed3dd 100644 --- a/include/Array.h +++ b/include/Array.h @@ -1,5 +1,5 @@ /* - * $Id: Array.h,v 1.7 2002/10/13 20:34:51 robertc Exp $ + * $Id: Array.h,v 1.8 2002/10/25 03:13:51 robertc Exp $ * * AUTHOR: Alex Rousskov * @@ -43,10 +43,10 @@ typedef struct { } Array; -extern Array *arrayCreate(void); +SQUIDCEXTERN Array *arrayCreate(void); SQUIDCEXTERN void arrayInit(Array * s); SQUIDCEXTERN void arrayClean(Array * s); -extern void arrayDestroy(Array * s); +SQUIDCEXTERN void arrayDestroy(Array * s); SQUIDCEXTERN void arrayAppend(Array * s, void *obj); SQUIDCEXTERN void arrayPreAppend(Array * s, int app_count); diff --git a/src/Makefile.am b/src/Makefile.am index 8287f7085c..56527708d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.40 2002/10/19 02:05:33 robertc Exp $ +# $Id: Makefile.am,v 1.41 2002/10/25 03:13:51 robertc Exp $ # # Uncomment and customize the following to suit your needs: # @@ -154,6 +154,7 @@ squid_SOURCES = \ forward.cc \ fqdncache.cc \ ftp.cc \ + Generic.h \ globals.h \ gopher.cc \ helper.cc \ diff --git a/src/Makefile.in b/src/Makefile.in index d17f762e41..e4b2738866 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,7 +16,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.258 2002/10/20 00:10:49 hno Exp $ +# $Id: Makefile.in,v 1.259 2002/10/25 03:13:51 robertc Exp $ # # Uncomment and customize the following to suit your needs: # @@ -245,6 +245,7 @@ squid_SOURCES = \ forward.cc \ fqdncache.cc \ ftp.cc \ + Generic.h \ globals.h \ gopher.cc \ helper.cc \ diff --git a/src/cbdata.cc b/src/cbdata.cc index 58f498ee36..6c59c608bd 100644 --- a/src/cbdata.cc +++ b/src/cbdata.cc @@ -1,10 +1,11 @@ /* - * $Id: cbdata.cc,v 1.48 2002/10/24 22:59:29 adrian Exp $ + * $Id: cbdata.cc,v 1.49 2002/10/25 03:13:51 robertc Exp $ * * DEBUG: section 45 Callback Data Registry * ORIGINAL AUTHOR: Duane Wessels * Modified by Moez Mahfoudh (08/12/2000) + * History added by Robert Collins (2002-10-25) * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -46,20 +47,45 @@ #include "squid.h" #include "Store.h" +#if CBDATA_DEBUG +#include "Stack.h" +#endif +#include "Generic.h" static int cbdataCount = 0; #if CBDATA_DEBUG dlink_list cbdataEntries; #endif +#if CBDATA_DEBUG +class CBDataCall { +public: + CBDataCall (char const *callLabel, char const *aFile, int aLine) : label(callLabel), file(aFile), line(aLine){} + char const *label; + char const *file; + int line; +}; +#endif + typedef struct _cbdata { +#if CBDATA_DEBUG + void dump(StoreEntry *)const; +#endif + void deleteSelf(); int valid; int locks; int type; #if CBDATA_DEBUG + void addHistory(char const *label, char const *file, int line) const + { + if (calls->count > 100) + return; + stackPush (calls, new CBDataCall(label, file, line)); + } dlink_node link; const char *file; int line; + Stack *calls; #endif long y; /* cookie used while debugging */ union { @@ -70,6 +96,9 @@ typedef struct _cbdata { } cbdata; static OBJH cbdataDump; +#ifdef CBDATA_DEBUG +static OBJH cbdataDumpHistory; +#endif struct CBDataIndex { MemPool *pool; @@ -81,6 +110,21 @@ int cbdata_types = 0; #define CBDATA_COOKIE (long)0xDEADBEEF #define CBDATA_CHECK(c) assert(c->y == ((long)c ^ CBDATA_COOKIE)) +void +_cbdata::deleteSelf() +{ +#if CBDATA_DEBUG + CBDataCall *aCall; + while ((aCall = (CBDataCall *)stackPop(calls))) + delete aCall; + stackDestroy(calls); +#endif + FREE *free_func = cbdata_index[type].free_func; + if (free_func) + free_func(&data); + memPoolFree(cbdata_index[type].pool, this); +} + static void cbdataInternalInitType(cbdata_type type, const char *name, int size, FREE * free_func) { @@ -117,6 +161,11 @@ cbdataInit(void) cachemgrRegister("cbdata", "Callback Data Registry Contents", cbdataDump, 0, 1); +#if CBDATA_DEBUG + cachemgrRegister("cbdatahistory", + "Detailed call history for all current cbdata contents", + cbdataDumpHistory, 0, 1); +#endif #define CREATE_CBDATA(type) cbdataInternalInitType(CBDATA_##type, #type, sizeof(type), NULL) #define CREATE_CBDATA_FREE(type, free_func) cbdataInternalInitType(CBDATA_##type, #type, sizeof(type), free_func) /* XXX @@ -153,14 +202,13 @@ cbdataInternalAlloc(cbdata_type type) p->type = type; p->valid = 1; p->locks = 0; -#if CBDATA_DEBUG - p->file = file; - p->line = line; -#endif p->y = (long) p ^ CBDATA_COOKIE; cbdataCount++; - #if CBDATA_DEBUG + p->file = file; + p->line = line; + p->calls = stackCreate(); + p->addHistory("Alloc", file, line); dlinkAdd(p, &p->link, &cbdataEntries); debug(45, 3) ("cbdataAlloc: %p %s:%d\n", &p->data, file, line); #endif @@ -175,7 +223,6 @@ cbdataInternalFree(void *p) #endif { cbdata *c; - FREE *free_func; c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); #if CBDATA_DEBUG debug(45, 3) ("cbdataFree: %p %s:%d\n", p, file, line); @@ -184,6 +231,9 @@ cbdataInternalFree(void *p) #endif CBDATA_CHECK(c); c->valid = 0; +#if CBDATA_DEBUG + c->addHistory("Free", file, line); +#endif if (c->locks) { debug(45, 3) ("cbdataFree: %p has %d locks, not freeing\n", p, c->locks); @@ -194,10 +244,7 @@ cbdataInternalFree(void *p) #if CBDATA_DEBUG dlinkDelete(&c->link, &cbdataEntries); #endif - free_func = cbdata_index[c->type].free_func; - if (free_func) - free_func((void *) p); - memPoolFree(cbdata_index[c->type].pool, c); + c->deleteSelf(); return NULL; } @@ -214,6 +261,7 @@ cbdataInternalLock(const void *p) c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); #if CBDATA_DEBUG debug(45, 3) ("cbdataLock: %p=%d %s:%d\n", p, c ? c->locks + 1 : -1, file, line); + c->addHistory("Reference", file, line); #else debug(45, 3) ("cbdataLock: %p=%d\n", p, c ? c->locks + 1 : -1); #endif @@ -230,12 +278,12 @@ cbdataInternalUnlock(const void *p) #endif { cbdata *c; - FREE *free_func; if (p == NULL) return; c = (cbdata *) (((char *) p) - OFFSET_OF(cbdata, data)); #if CBDATA_DEBUG debug(45, 3) ("cbdataUnlock: %p=%d %s:%d\n", p, c ? c->locks - 1 : -1, file, line); + c->addHistory("Dereference", file, line); #else debug(45, 3) ("cbdataUnlock: %p=%d\n", p, c ? c->locks - 1 : -1); #endif @@ -250,10 +298,7 @@ cbdataInternalUnlock(const void *p) #if CBDATA_DEBUG dlinkDelete(&c->link, &cbdataEntries); #endif - free_func = cbdata_index[c->type].free_func; - if (free_func) - free_func((void *) p); - memPoolFree(cbdata_index[c->type].pool, c); + c->deleteSelf(); } int @@ -293,25 +338,35 @@ cbdataInternalReferenceDoneValid(void **pp, void **tp) } } +#if CBDATA_DEBUG +void +_cbdata::dump(StoreEntry *sentry) const +{ + storeAppendPrintf(sentry, "%c%p\t%d\t%d\t%20s:%-5d\n", valid ? ' ' : + '!', &data, type, locks, file, line); +} + +struct CBDataDumper : public unary_function<_cbdata, void> +{ + CBDataDumper(StoreEntry *anEntry):where(anEntry){} + void operator()(_cbdata const &x) { + x.dump(where); + } + StoreEntry *where; +}; +#endif static void cbdataDump(StoreEntry * sentry) { -#if CBDATA_DEBUG - dlink_node *n; - cbdata *p; - int i; -#endif storeAppendPrintf(sentry, "%d cbdata entries\n", cbdataCount); #if CBDATA_DEBUG storeAppendPrintf(sentry, "Pointer\tType\tLocks\tAllocated by\n"); - for (n = cbdataEntries.head; n; n = n->next) { - p = (cbdata *)n->data; - storeAppendPrintf(sentry, "%c%p\t%d\t%d\t%20s:%-5d\n", p->valid ? ' ' : '!', &p->data, p->type, p->locks, p->file, p->line); - } + CBDataDumper dumper(sentry); + for_each (cbdataEntries, dumper); storeAppendPrintf(sentry, "\n"); storeAppendPrintf(sentry, "types\tsize\tallocated\ttotal\n"); - for (i = 1; i < cbdata_types; i++) { + for (int i = 1; i < cbdata_types; i++) { MemPool *pool = cbdata_index[i].pool; if (pool) { int obj_size = pool->obj_size - OFFSET_OF(cbdata, data); @@ -323,3 +378,46 @@ cbdataDump(StoreEntry * sentry) #endif storeAppendPrintf(sentry, "\nsee also \"Memory utilization\" for detailed per type statistics\n"); } + +#if CBDATA_DEBUG + +template +T& for_each(Stack const &collection, T& visitor) +{ + for (int index = 0; index < collection.count; ++index) + visitor(*(typename T::argument_type const *)collection.items[index]); + return visitor; +}; + +struct CBDataCallDumper : public unary_function +{ + CBDataCallDumper (StoreEntry *anEntry):where(anEntry){} + void operator()(CBDataCall const &x) { + storeAppendPrintf(where, "%s\t%s\t%d\n", x.label, x.file, x.line); + } + StoreEntry *where; +}; + +struct CBDataHistoryDumper : public CBDataDumper +{ + CBDataHistoryDumper(StoreEntry *anEntry):CBDataDumper(anEntry),where(anEntry), callDumper(anEntry){} + void operator()(_cbdata const &x) { + CBDataDumper::operator()(x); + storeAppendPrintf(where, "\n"); + storeAppendPrintf(where, "Action\tFile\tLine\n"); + for_each (*x.calls,callDumper); + storeAppendPrintf(where, "\n"); + } + StoreEntry *where; + CBDataCallDumper callDumper; +}; + +void +cbdataDumpHistory(StoreEntry *sentry) +{ + storeAppendPrintf(sentry, "%d cbdata entries\n", cbdataCount); + storeAppendPrintf(sentry, "Pointer\tType\tLocks\tAllocated by\n"); + CBDataHistoryDumper dumper(sentry); + for_each (cbdataEntries, dumper); +} +#endif