From: Lucian Grijincu Date: Tue, 21 Jun 2016 20:40:46 +0000 (-0700) Subject: folly:: singleton: ubsan: fix calling overriden method from ctor X-Git-Tag: 2016.07.26~131 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=31fa09caf910f576682b4832e744b6183358d904;p=folly.git folly:: singleton: ubsan: fix calling overriden method from ctor Summary: Ubsan complains when overriden method is called from ctor: ``` 0x000000b04d40: note: object is of type 'folly::detail::SingletonHolder' 00 00 00 00 08 50 c3 8d da 7f 00 00 e8 4f c3 8d da 7f 00 00 18 0d 4c b4 da 7f 00 00 a0 16 90 00 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for 'folly::detail::SingletonHolder' ``` called from `folly::SingletonVault::registerSingleton(folly::detail::SingletonHolderBase*)` Reviewed By: ot Differential Revision: D3462037 fbshipit-source-id: 6df283dd53df42d5d318990f60aba370ceed6395 --- diff --git a/folly/Singleton-inl.h b/folly/Singleton-inl.h index a643e037..6c6e995c 100644 --- a/folly/Singleton-inl.h +++ b/folly/Singleton-inl.h @@ -54,7 +54,7 @@ void SingletonHolder::registerSingleton(CreateFunc c, TeardownFunc t) { * Singleton b([] { return new int(4); }); * */ - singletonWarnDoubleRegistrationAndAbort(type_); + singletonWarnDoubleRegistrationAndAbort(type()); } create_ = std::move(c); @@ -66,8 +66,8 @@ void SingletonHolder::registerSingleton(CreateFunc c, TeardownFunc t) { template void SingletonHolder::registerSingletonMock(CreateFunc c, TeardownFunc t) { if (state_ == SingletonHolderState::NotRegistered) { - LOG(FATAL) - << "Registering mock before singleton was registered: " << type_.name(); + LOG(FATAL) << "Registering mock before singleton was registered: " + << type().name(); } destroyInstance(); @@ -89,7 +89,7 @@ T* SingletonHolder::get() { throw std::runtime_error( "Raw pointer to a singleton requested after its destruction." " Singleton type is: " + - type_.name()); + type().name()); } return instance_ptr_; @@ -125,11 +125,6 @@ folly::ReadMostlySharedPtr SingletonHolder::try_get_fast() { return instance_weak_fast_.lock(); } -template -TypeDescriptor SingletonHolder::type() { - return type_; -} - template bool SingletonHolder::hasLiveInstance() { return !instance_weak_.expired(); @@ -145,7 +140,7 @@ void SingletonHolder::destroyInstance() { std::chrono::steady_clock::now() + kDestroyWaitTime); if (!wait_result) { print_destructor_stack_trace_->store(true); - LOG(ERROR) << "Singleton of type " << type_.name() << " has a " + LOG(ERROR) << "Singleton of type " << type().name() << " has a " << "living reference at destroyInstances time; beware! Raw " << "pointer is " << instance_ptr_ << ". It is very likely " << "that some other singleton is holding a shared_ptr to it. " @@ -156,10 +151,10 @@ void SingletonHolder::destroyInstance() { } template -SingletonHolder::SingletonHolder(TypeDescriptor type__, - SingletonVault& vault) : - type_(type__), vault_(vault) { -} +SingletonHolder::SingletonHolder( + TypeDescriptor typeDesc, + SingletonVault& vault) + : SingletonHolderBase(typeDesc), vault_(vault) {} template bool SingletonHolder::creationStarted() { @@ -181,7 +176,7 @@ template void SingletonHolder::createInstance() { if (creating_thread_.load(std::memory_order_acquire) == std::this_thread::get_id()) { - LOG(FATAL) << "circular singleton dependency: " << type_.name(); + LOG(FATAL) << "circular singleton dependency: " << type().name(); } std::lock_guard entry_lock(mutex_); @@ -192,9 +187,10 @@ void SingletonHolder::createInstance() { SingletonHolderState::NotRegistered) { auto ptr = SingletonVault::stackTraceGetter().load(); LOG(FATAL) << "Creating instance for unregistered singleton: " - << type_.name() << "\n" + << type().name() << "\n" << "Stacktrace:" - << "\n" << (ptr ? (*ptr)() : "(not available)"); + << "\n" + << (ptr ? (*ptr)() : "(not available)"); } if (state_.load(std::memory_order_acquire) == SingletonHolderState::Living) { @@ -219,7 +215,7 @@ void SingletonHolder::createInstance() { auto print_destructor_stack_trace = std::make_shared>(false); auto teardown = teardown_; - auto type_name = type_.name(); + auto type_name = type().name(); // Can't use make_shared -- no support for a custom deleter, sadly. std::shared_ptr instance( @@ -264,7 +260,7 @@ void SingletonHolder::createInstance() { { RWSpinLock::WriteHolder wh(&vault_.mutex_); - vault_.creation_order_.push_back(type_); + vault_.creation_order_.push_back(type()); } } diff --git a/folly/Singleton.h b/folly/Singleton.h index 78fa83d2..89bc28be 100644 --- a/folly/Singleton.h +++ b/folly/Singleton.h @@ -218,13 +218,19 @@ class TypeDescriptorHasher { // SingletonHolders. class SingletonHolderBase { public: + explicit SingletonHolderBase(TypeDescriptor typeDesc) : type_(typeDesc) {} virtual ~SingletonHolderBase() = default; - virtual TypeDescriptor type() = 0; + TypeDescriptor type() const { + return type_; + } virtual bool hasLiveInstance() = 0; virtual void createInstance() = 0; virtual bool creationStarted() = 0; virtual void destroyInstance() = 0; + + private: + TypeDescriptor type_; }; // An actual instance of a singleton, tracking the instance itself, @@ -246,7 +252,6 @@ struct SingletonHolder : public SingletonHolderBase { void registerSingleton(CreateFunc c, TeardownFunc t); void registerSingletonMock(CreateFunc c, TeardownFunc t); - virtual TypeDescriptor type() override; virtual bool hasLiveInstance() override; virtual void createInstance() override; virtual bool creationStarted() override; @@ -261,7 +266,6 @@ struct SingletonHolder : public SingletonHolderBase { Living, }; - TypeDescriptor type_; SingletonVault& vault_; // mutex protects the entire entry during construction/destruction