[llvm] [Support] Fix memory leak in `Timer.cpp` on shutdown (PR #159983)
Alexandre Ganea via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 21 12:52:09 PDT 2025
https://github.com/aganea updated https://github.com/llvm/llvm-project/pull/159983
>From 5d7d09a118014a6efd008a26a6dda8eedc4f1733 Mon Sep 17 00:00:00 2001
From: Alexandre Ganea <alex_toresh at yahoo.fr>
Date: Sun, 21 Sep 2025 11:07:20 -0400
Subject: [PATCH 1/2] [Support] Fix memory leak in Timer on shutdown
---
llvm/lib/Support/Timer.cpp | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 75ec299a98376..20f51afe4ee74 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -57,6 +57,7 @@ static SignpostEmitter &signposts();
static sys::SmartMutex<true> &timerLock();
static TimerGroup &defaultTimerGroup();
static Name2PairMap &namedGroupedTimers();
+static bool isTimerGlobalsConstructed();
//===----------------------------------------------------------------------===//
//
@@ -305,14 +306,24 @@ TimerGroup::~TimerGroup() {
PrintQueuedTimers(*OutStream);
}
+ auto unlink = [&]() {
+ *Prev = Next;
+ if (Next)
+ Next->Prev = Prev;
+ };
+
+ // If the managed instance is already dead, it means we're in the CRT
+ // destruction, so no need to lock.
+ if (!isTimerGlobalsConstructed()) {
+ unlink();
+ return;
+ }
+
// Remove the group from the TimerGroupList.
sys::SmartScopedLock<true> L(timerLock());
- *Prev = Next;
- if (Next)
- Next->Prev = Prev;
+ unlink();
}
-
void TimerGroup::removeTimer(Timer &T) {
sys::SmartScopedLock<true> L(timerLock());
@@ -557,3 +568,7 @@ void TimerGroup::constructForStatistics() {
}
void *TimerGroup::acquireTimerGlobals() { return ManagedTimerGlobals.claim(); }
+
+static bool isTimerGlobalsConstructed() {
+ return ManagedTimerGlobals.isConstructed();
+}
>From 5c0e7c9ebe1b4e54298f74a6e092819ee1e56baa Mon Sep 17 00:00:00 2001
From: Alexandre Ganea <alex_toresh at yahoo.fr>
Date: Sun, 21 Sep 2025 15:51:45 -0400
Subject: [PATCH 2/2] Clarify comment.
---
llvm/lib/Support/Timer.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 20f51afe4ee74..67483ba9dd655 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -312,8 +312,10 @@ TimerGroup::~TimerGroup() {
Next->Prev = Prev;
};
- // If the managed instance is already dead, it means we're in the CRT
- // destruction, so no need to lock.
+ // TimerGlobals is always created implicity, through a call to timerLock(),
+ // when a TimeGroup is created. On CRT shutdown, the TimerGlobals instance
+ // might have been destroyed already. Avoid re-creating it if calling
+ // timerLock().
if (!isTimerGlobalsConstructed()) {
unlink();
return;
More information about the llvm-commits
mailing list