LEAK_CHECK_MODE had not worked since before 2006 commit
afec404. The
disabled code does not compile since 2012 commit
b65ce00 and would crash
current Squids during shutdown. We should not fix it because the
underlying "delete essentialService" idea is deeply flawed.
Writing correct code that uses essential modules/services that may
"suddenly" disappear or crash is nearly impossible. The trickle of
assertions due to missing Store::Root() is a case in point. These risks
and efforts are also unnecessary: We can and should build APIs that
provide essential services without disappearing or crashing. Keeping
heap-allocated service objects during shutdown helps with that.
Valgrind and other modern leak detection tools are capable of
distinguishing still-reachable at-exit memory from runtime memory leaks.
We do not need to delete all still-reachable at-exit objects to enable
that leak detection functionality.
The OS will reclaim allocated heap memory anyway.
N.B. Despite the legacy code implications, we should distinguish
low-level new/delete (a.k.a. fooInit() and fooFree()) memory management
code (which is an internal service matter that essential service users
should not be exposed to!) with configure-reconfigure-reconfigure-sync
events. There is value in notifying services about configuration
(changes) and various shutdown stages, of course. We already have the
RunnersRegistry API for handling such notifications.
Even without explicit "delete essentialService" calls, we may still have
problems during C++ post-exit() cleanup where destructors of various
globals are called "concurrently", with few order guarantees. We should
avoid non-heap-allocated globals with "complicated" destructors, but
their elimination is out of scope here.
#define SQUID_UDP_SO_RCVBUF SQUID_DETECT_UDP_SO_RCVBUF
#endif
-/*
- * Determine if this is a leak check build or standard
- */
-#if PURIFY || WITH_VALGRIND
-#define LEAK_CHECK_MODE 1
-#endif
-
/* temp hack: needs to be pre-defined for now. */
#define SQUID_MAXPATHLEN 256
/// \ingroup StoreAPI
void storeConfigure(void);
-/// \ingroup StoreAPI
-void storeFreeMemory(void);
-
/// \ingroup StoreAPI
int expiresMoreThan(time_t, time_t);
debugs(77, 9, "ClientInfo destructed, this=" << static_cast<void*>(this));
}
-void
-clientdbFreeMemory(void)
-{
- hashFreeItems(client_table, clientdbFreeItem);
- hashFreeMemory(client_table);
- client_table = nullptr;
-}
-
static void
clientdbScheduledGC(void *)
{
void clientdbUpdate(const Ip::Address &, const LogTags &, AnyP::ProtocolType, size_t);
int clientdbCutoffDenied(const Ip::Address &);
void clientdbDump(StoreEntry *);
-void clientdbFreeMemory(void);
int clientdbEstablished(const Ip::Address &, int);
#if USE_DELAY_POOLS
EventScheduler::GetInstance()->dump(sentry);
}
-void
-eventFreeMemory(void)
-{
- EventScheduler::GetInstance()->clean();
-}
-
int
eventFind(EVH * func, void *arg)
{
void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int);
void eventDelete(EVH * func, void *arg);
void eventInit(void);
-void eventFreeMemory(void);
int eventFind(EVH *, void *);
class ev_entry
static int fqdncacheExpiredEntry(const fqdncache_entry *);
static void fqdncacheLockEntry(fqdncache_entry * f);
static void fqdncacheUnlockEntry(fqdncache_entry * f);
-static FREE fqdncacheFreeEntry;
static void fqdncacheAddEntry(fqdncache_entry * f);
/// \ingroup FQDNCacheInternal
fqdncacheRelease(f);
}
-/// \ingroup FQDNCacheInternal
-static void
-fqdncacheFreeEntry(void *data)
-{
- fqdncache_entry *f = (fqdncache_entry *)data;
- delete f;
-}
-
fqdncache_entry::~fqdncache_entry()
{
for (int k = 0; k < (int)name_count; ++k)
xfree(error_message);
}
-/// \ingroup FQDNCacheAPI
-void
-fqdncacheFreeMemory(void)
-{
- hashFreeItems(fqdn_table, fqdncacheFreeEntry);
- hashFreeMemory(fqdn_table);
- fqdn_table = nullptr;
-}
-
/**
\ingroup FQDNCacheAPI
*
void fqdncache_init(void);
void fqdnStats(StoreEntry *);
-void fqdncacheFreeMemory(void);
void fqdncache_restart(void);
void fqdncache_purgelru(void *);
void fqdncacheAddEntryFromHosts(char *addr, SBufList &hostnames);
static net_db_peer *netdbPeerAdd(netdbEntry * n, CachePeer * e);
static const char *netdbPeerName(const char *name);
static IPH netdbSendPing;
-static FREE netdbFreeNameEntry;
-static FREE netdbFreeNetdbEntry;
static STCB netdbExchangeHandleReply;
/* We have to keep a local list of CachePeer names. The Peers structure
return wordlistAdd(&peer_names, name);
}
-static void
-netdbFreeNetdbEntry(void *data)
-{
- netdbEntry *n = (netdbEntry *)data;
- safe_free(n->peers);
- delete n;
-}
-
-static void
-netdbFreeNameEntry(void *data)
-{
- net_db_name *x = (net_db_name *)data;
- delete x;
-}
-
static void
netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
{
#endif
}
-void
-netdbFreeMemory(void)
-{
-#if USE_ICMP
- hashFreeItems(addr_table, netdbFreeNetdbEntry);
- hashFreeMemory(addr_table);
- addr_table = nullptr;
- hashFreeItems(host_table, netdbFreeNameEntry);
- hashFreeMemory(host_table);
- host_table = nullptr;
- wordlistDestroy(&peer_names);
- peer_names = nullptr;
-#endif
-}
-
void
netdbDump(StoreEntry * sentry)
{
void netdbPingSite(const char *hostname);
void netdbDump(StoreEntry *);
-void netdbFreeMemory(void);
int netdbHostHops(const char *host);
int netdbHostRtt(const char *host);
void netdbUpdatePeer(const AnyP::Uri &, CachePeer *, int rtt, int hops);
xfree(hash.key);
}
-/// \ingroup IPCacheAPI
-void
-ipcacheFreeMemory(void)
-{
- hashFreeItems(ip_table, ipcacheFreeEntry);
- hashFreeMemory(ip_table);
- ip_table = nullptr;
-}
-
/**
\ingroup IPCacheAPI
*
void ipcache_init(void);
void ipcacheMarkBadAddr(const char *name, const Ip::Address &);
void ipcacheMarkGoodAddr(const char *name, const Ip::Address &);
-void ipcacheFreeMemory(void);
void ipcache_restart(void);
int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr);
Store::Root().sync(); /* Flush log close */
StoreFileSystem::FreeAllFs();
DiskIOModule::FreeAllModules();
-#if LEAK_CHECK_MODE && 0 /* doesn't work at the moment */
-
- configFreeMemory();
- storeFreeMemory();
- /*stmemFreeMemory(); */
- netdbFreeMemory();
- ipcacheFreeMemory();
- fqdncacheFreeMemory();
- asnFreeMemory();
- clientdbFreeMemory();
- statFreeMemory();
- eventFreeMemory();
- mimeFreeMemory();
- errorClean();
-#endif
Store::FreeMemory();
fdDumpOpen();
stats.hitValidationFailures);
}
-void
-statFreeMemory(void)
-{
- // TODO: replace with delete[]
- for (int i = 0; i < N_COUNT_HIST; ++i)
- CountHist[i] = StatCounters();
-
- for (int i = 0; i < N_COUNT_HOUR_HIST; ++i)
- CountHourHist[i] = StatCounters();
-}
-
static void
statPeerSelect(StoreEntry * sentry)
{
#define SQUID_STAT_H_
void statInit(void);
-void statFreeMemory(void);
double median_svc_get(int, int);
void pconnHistCount(int, int);
int stat5minClientRequests(void);
}
}
-void
-storeFreeMemory(void)
-{
- Store::FreeMemory();
-#if USE_CACHE_DIGESTS
- delete store_digest;
-#endif
- store_digest = nullptr;
-}
-
int
expiresMoreThan(time_t expires, time_t when)
{
void clientdbUpdate(const Ip::Address &, const LogTags &, AnyP::ProtocolType, size_t) STUB
int clientdbCutoffDenied(const Ip::Address &) STUB_RETVAL(-1)
void clientdbDump(StoreEntry *) STUB
-void clientdbFreeMemory(void) STUB
int clientdbEstablished(const Ip::Address &, int) STUB_RETVAL(-1)
#if USE_DELAY_POOLS
void clientdbSetWriteLimiter(ClientInfo *, const int,const double,const double) STUB
void eventAddIsh(const char *, EVH *, void *, double, int) STUB
void eventDelete(EVH *, void *) STUB
void eventInit(void) STUB
-void eventFreeMemory(void) STUB
int eventFind(EVH *, void *) STUB_RETVAL(-1)
// ev_entry::ev_entry(char const * name, EVH * func, void *arg, double when, int weight, bool cbdata) STUB
void fqdncache_init(void) STUB
void fqdnStats(StoreEntry *) STUB
-void fqdncacheFreeMemory(void) STUB
void fqdncache_restart(void) STUB
void fqdncache_purgelru(void *) STUB
void fqdncacheAddEntryFromHosts(char *, SBufList &) STUB
void ipcache_init(void) STUB
void ipcacheMarkBadAddr(const char *, const Ip::Address &) STUB
void ipcacheMarkGoodAddr(const char *, const Ip::Address &) STUB
-void ipcacheFreeMemory(void) STUB
void ipcache_restart(void) STUB
int ipcacheAddEntryFromHosts(const char *, const char *) STUB_RETVAL(-1)
void netdbHandlePingReply(const Ip::Address &, int, int) STUB
void netdbPingSite(const char *) STUB
void netdbDump(StoreEntry *) STUB
-void netdbFreeMemory(void) STUB
int netdbHostHops(const char *) STUB_RETVAL(-1)
int netdbHostRtt(const char *) STUB_RETVAL(-1)
void netdbUpdatePeer(const AnyP::Uri &, CachePeer *, int, int) STUB