summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-06-23 16:13:55 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-07-03 02:49:27 -0400
commitb835112cbeaa6e34a8bae7b7697bdf2826edaa9a (patch)
tree5435f692c28a6f5af860b3495728aeb1b0c860f1
parent8cc7274b8de254c7266b61fadbc6795dc37bd1e9 (diff)
downloadhaskell-b835112cbeaa6e34a8bae7b7697bdf2826edaa9a.tar.gz
rts/ProfHeap: Free old allocations when reinitialising Censuses
Previously when not LDV profiling we would repeatedly reinitialise `censuses[0]` with `initEra`. This failed to free the `Arena` and `HashTable` from the old census, resulting in a memory leak. Fixes #18348.
-rw-r--r--rts/ProfHeap.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index 0b7b386249..06bff048e7 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -347,6 +347,16 @@ LDV_recordDead( const StgClosure *c, uint32_t size )
STATIC_INLINE void
initEra(Census *census)
{
+ // N.B. When not LDV profiling we reinitialise the same Census over
+ // and over again. Consequently, we need to ensure that we free the
+ // resources from the previous census.
+ if (census->hash) {
+ freeHashTable(census->hash, NULL);
+ }
+ if (census->arena) {
+ arenaFree(census->arena);
+ }
+
census->hash = allocHashTable();
census->ctrs = NULL;
census->arena = newArena();
@@ -511,6 +521,11 @@ initHeapProfiling(void)
censuses = stgMallocBytes(sizeof(Census) * n_censuses, "initHeapProfiling");
+ // Ensure that arena and hash are NULL since otherwise initEra will attempt to free them.
+ for (unsigned int i=0; i < n_censuses; i++) {
+ censuses[i].arena = NULL;
+ censuses[i].hash = NULL;
+ }
initEra( &censuses[era] );
/* initProfilingLogFile(); */