From 278d263c9532dabb110dcfc74a50fdc92256d101 Mon Sep 17 00:00:00 2001 From: Andrii Grynenko Date: Fri, 20 Mar 2015 12:17:17 -0700 Subject: [PATCH] Make folly::Singleton DFATAL as late as possible Summary: We want to print all destructor stack-traces if Singleton destruction happens eventually (even after destroyInstances() was done). Test Plan: unit test Reviewed By: chip@fb.com Subscribers: folly-diffs@, yfeldblum FB internal diff: D1929881 Signature: t1:1929881:1426878091:5993d544c0f84bdbf8bcdd420ef01fb7bf88ac3f --- folly/experimental/Singleton.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/folly/experimental/Singleton.cpp b/folly/experimental/Singleton.cpp index 7421f4bc..1c39326e 100644 --- a/folly/experimental/Singleton.cpp +++ b/folly/experimental/Singleton.cpp @@ -26,6 +26,29 @@ constexpr std::chrono::seconds SingletonHolderBase::kDestroyWaitTime; } +namespace { + +struct FatalHelper { + ~FatalHelper() { + if (!leakedSingletons_.empty()) { + std::string leakedTypes; + for (const auto& singleton : leakedSingletons_) { + leakedTypes += "\t" + singleton.name() + "\n"; + } + LOG(DFATAL) << "Singletons of the following types had living references " + << "after destroyInstances was finished:\n" << leakedTypes + << "beware! It is very likely that those singleton instances " + << "are leaked."; + } + } + + std::vector leakedSingletons_; +}; + +FatalHelper __attribute__ ((__init_priority__ (101))) fatalHelper; + +} + SingletonVault::~SingletonVault() { destroyInstances(); } void SingletonVault::destroyInstances() { @@ -55,10 +78,7 @@ void SingletonVault::destroyInstances() { continue; } - LOG(DFATAL) << "Singleton of type " << singleton->type().name() << " has " - << "a living reference after destroyInstances was finished;" - << "beware! It is very likely that this singleton instance " - << "will be leaked."; + fatalHelper.leakedSingletons_.push_back(singleton->type()); } } -- 2.34.1