Skip to content

Commit e52792e

Browse files
authored
[Support] Fix memory leak in Timer.cpp on shutdown (#159983)
This used to happen in the global destruction, after `main()` has exited. Previously, we were re-creating the `llvm::TimerGlobals` object at this point. <img width="855" height="270" alt="image" src="https://github.com/user-attachments/assets/757e9416-a74a-406a-841e-d3e4cc6a69a1" />
1 parent da55134 commit e52792e

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

llvm/lib/Support/Timer.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static SignpostEmitter &signposts();
5757
static sys::SmartMutex<true> &timerLock();
5858
static TimerGroup &defaultTimerGroup();
5959
static Name2PairMap &namedGroupedTimers();
60+
static bool isTimerGlobalsConstructed();
6061

6162
//===----------------------------------------------------------------------===//
6263
//
@@ -305,14 +306,26 @@ TimerGroup::~TimerGroup() {
305306
PrintQueuedTimers(*OutStream);
306307
}
307308

309+
auto unlink = [&]() {
310+
*Prev = Next;
311+
if (Next)
312+
Next->Prev = Prev;
313+
};
314+
315+
// TimerGlobals is always created implicity, through a call to timerLock(),
316+
// when a TimeGroup is created. On CRT shutdown, the TimerGlobals instance
317+
// might have been destroyed already. Avoid re-creating it if calling
318+
// timerLock().
319+
if (!isTimerGlobalsConstructed()) {
320+
unlink();
321+
return;
322+
}
323+
308324
// Remove the group from the TimerGroupList.
309325
sys::SmartScopedLock<true> L(timerLock());
310-
*Prev = Next;
311-
if (Next)
312-
Next->Prev = Prev;
326+
unlink();
313327
}
314328

315-
316329
void TimerGroup::removeTimer(Timer &T) {
317330
sys::SmartScopedLock<true> L(timerLock());
318331

@@ -557,3 +570,7 @@ void TimerGroup::constructForStatistics() {
557570
}
558571

559572
void *TimerGroup::acquireTimerGlobals() { return ManagedTimerGlobals.claim(); }
573+
574+
static bool isTimerGlobalsConstructed() {
575+
return ManagedTimerGlobals.isConstructed();
576+
}

0 commit comments

Comments
 (0)