diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-06-23 16:13:55 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-06-24 16:08:56 -0400 |
commit | e90af2f456f0430d11eea19b285986e732034798 (patch) | |
tree | e8cb29b49ce1d6029fb9b786f33a68ee51ab234c | |
parent | a50487a5644dc4df2248b7cd35c77e39ab4f963c (diff) | |
download | haskell-e90af2f456f0430d11eea19b285986e732034798.tar.gz |
rts/ProfHeap: Free old allocations when reinitialising Censuseswip/free-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(); */ |