void singletonWarnDestroyInstanceLeak( const TypeDescriptor& type, const void* ptr) { LOG(ERROR) << "Singleton of type " << type.name() << " has a " << "living reference at destroyInstances time; beware! Raw " << "pointer is " << ptr << ". It is very likely " << "that some other singleton is holding a shared_ptr to it. " << "This singleton will be leaked (even if a shared_ptr to it " << "is eventually released)." << "Make sure dependencies between these singletons are " << "properly defined."; }
void singletonPrintDestructionStackTrace(const TypeDescriptor& type) { std::string output = "Singleton " + type.name() + " was released.\n"; auto stack_trace_getter = SingletonVault::stackTraceGetter().load(); auto stack_trace = stack_trace_getter ? stack_trace_getter() : ""; if (stack_trace.empty()) { output += "Failed to get release stack trace."; } else { output += "Release stack trace:\n"; output += stack_trace; } LOG(ERROR) << output; }
[[noreturn]] void singletonWarnCreateBeforeRegistrationCompleteAndAbort( const TypeDescriptor& type) { auto stack_trace_getter = SingletonVault::stackTraceGetter().load(); auto stack_trace = stack_trace_getter ? stack_trace_getter() : ""; if (!stack_trace.empty()) { stack_trace = "Stack trace:\n" + stack_trace; } LOG(FATAL) << "Singleton " << type.name() << " requested before " << "registrationComplete() call.\n" << "This usually means that either main() never called " << "folly::init, or singleton was requested before main() " << "(which is not allowed).\n" << stack_trace; }
[[noreturn]] void singletonWarnCreateCircularDependencyAndAbort( const TypeDescriptor& type) { LOG(FATAL) << "circular singleton dependency: " << type.name(); }
[[noreturn]] void singletonWarnRegisterMockEarlyAndAbort( const TypeDescriptor& type) { LOG(FATAL) << "Registering mock before singleton was registered: " << type.name(); }
void singletonPrintDestructionStackTrace(const TypeDescriptor& type) { auto trace = detail::getSingletonStackTrace(); LOG(ERROR) << "Singleton " << type.name() << " was released.\n" << "Stacktrace:\n" << (trace != "" ? trace : "(not available)"); }