diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-06-23 16:13:55 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-07-03 02:49:27 -0400 |
commit | b835112cbeaa6e34a8bae7b7697bdf2826edaa9a (patch) | |
tree | 5435f692c28a6f5af860b3495728aeb1b0c860f1 | |
parent | 8cc7274b8de254c7266b61fadbc6795dc37bd1e9 (diff) | |
download | haskell-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.c | 15 |
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(); */ |