From f254938de8f30ad36c95d123e40478cfeaf72434 Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Thu, 6 Jul 2017 02:13:11 +0200 Subject: [PATCH 1/2] Fix leaking main thread held memory - Release such memory explicitly by `destroy`ing the main thread on threading module termination - Remove explicit _tlsRanges.popBack call as now _tlsRanges will have already been released in that case via core.thread.thread_term -> ~Thread on the main thread -> rt.tlsgc.destroy -> rt.sections.finiTLSRanges --- src/core/thread.d | 3 +++ src/rt/sections_elf_shared.d | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 4f99cbbc31..3bb9eb5f17 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -2043,6 +2043,9 @@ extern (C) void thread_init() */ extern (C) void thread_term() { + try destroy(Thread.sm_main); catch (Exception) {} + Thread.sm_main = null; + assert(Thread.sm_tbeg && Thread.sm_tlen == 1); assert(!Thread.nAboutToStart); if (Thread.pAboutToStart) // in case realloc(p, 0) doesn't return null diff --git a/src/rt/sections_elf_shared.d b/src/rt/sections_elf_shared.d index a95328b5fb..c687028c29 100644 --- a/src/rt/sections_elf_shared.d +++ b/src/rt/sections_elf_shared.d @@ -461,8 +461,6 @@ extern(C) void _d_dso_registry(CompilerDSOData* data) else { // static DSOs are unloaded in reverse order - assert(pdso._tlsSize == _tlsRanges.back.length); - _tlsRanges.popBack(); assert(pdso == _loadedDSOs.back); _loadedDSOs.popBack(); } From c4f0d0da70f00d944217275e5e2d9d460ece59f0 Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Thu, 6 Jul 2017 02:31:14 +0200 Subject: [PATCH 2/2] Don't drop main thread destruction exceptions --- src/core/thread.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/thread.d b/src/core/thread.d index 3bb9eb5f17..6642e2f4ec 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -2043,7 +2043,7 @@ extern (C) void thread_init() */ extern (C) void thread_term() { - try destroy(Thread.sm_main); catch (Exception) {} + destroy(Thread.sm_main); Thread.sm_main = null; assert(Thread.sm_tbeg && Thread.sm_tlen == 1);