diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index cd5c2a7f0e8dccceb497b34f892c65f4fcb23757..479244400d13c5a2a8aa9acc97ae17569be5e0dd 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -38,7 +38,11 @@
 
 namespace {
 void log(LLError::ELevel level,
-         const char* p1="", const char* p2="", const char* p3="", const char* p4="");
+         const char* p1, const char* p2, const char* p3, const char* p4);
+
+void logdebugs(const char* p1="", const char* p2="", const char* p3="", const char* p4="");
+
+bool oktolog();
 } // anonymous namespace
 
 // Our master list of all LLSingletons is itself an LLSingleton. We used to
@@ -95,38 +99,64 @@ LLSingletonBase::list_t& LLSingletonBase::get_initializing()
     return sList;
 }
 
-LLSingletonBase::LLSingletonBase():
+LLSingletonBase::LLSingletonBase(const char* name):
     mCleaned(false),
     mDeleteSingleton(NULL)
 {
     // Make this the currently-initializing LLSingleton.
-    push_initializing();
+    push_initializing(name);
 }
 
 LLSingletonBase::~LLSingletonBase() {}
 
-void LLSingletonBase::push_initializing()
+void LLSingletonBase::push_initializing(const char* name)
 {
+    // log BEFORE pushing so logging singletons don't cry circularity
+    log_initializing("Pushing", name);
     get_initializing().push_back(this);
 }
 
 void LLSingletonBase::pop_initializing()
 {
     list_t& list(get_initializing());
+
     if (list.empty())
     {
         logerrs("Underflow in stack of currently-initializing LLSingletons at ",
                 demangle(typeid(*this).name()).c_str(), "::getInstance()");
     }
-    if (list.back() != this)
+
+    // Now we know list.back() exists: capture it
+    LLSingletonBase* back(list.back());
+    // and pop it
+    list.pop_back();
+
+    if (back != this)
     {
-        LLSingletonBase* back(list.back());
         logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
                 demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ",
                 demangle(typeid(*back).name()).c_str());
     }
-    // Here we're sure that list.back() == this. Whew, pop it.
-    list.pop_back();
+
+    // log AFTER popping so logging singletons don't cry circularity
+    log_initializing("Popping", typeid(*back).name());
+}
+
+//static
+void LLSingletonBase::log_initializing(const char* verb, const char* name)
+{
+    if (oktolog())
+    {
+        LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';';
+        list_t& list(get_initializing());
+        for (list_t::const_reverse_iterator ri(list.rbegin()), rend(list.rend());
+             ri != rend; ++ri)
+        {
+            LLSingletonBase* sb(*ri);
+            LL_CONT << ' ' << demangle(typeid(*sb).name());
+        }
+        LL_ENDL;
+    }
 }
 
 void LLSingletonBase::capture_dependency(EInitState initState)
@@ -181,8 +211,8 @@ void LLSingletonBase::capture_dependency(EInitState initState)
             if (current->mDepends.insert(this).second)
             {
                 // only log the FIRST time we hit this dependency!
-                log(LLError::LEVEL_DEBUG, demangle(typeid(*current).name()).c_str(),
-                    " depends on ", demangle(typeid(*this).name()).c_str());
+                logdebugs(demangle(typeid(*current).name()).c_str(),
+                          " depends on ", demangle(typeid(*this).name()).c_str());
             }
         }
     }
@@ -240,8 +270,8 @@ void LLSingletonBase::cleanupAll()
         {
             sp->mCleaned = true;
 
-            log(LLError::LEVEL_DEBUG, "calling ",
-                demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()");
+            logdebugs("calling ",
+                      demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()");
             try
             {
                 sp->cleanupSingleton();
@@ -280,7 +310,7 @@ void LLSingletonBase::deleteAll()
             else
             {
                 // properly initialized: call it.
-                log(LLError::LEVEL_DEBUG, "calling ", name.c_str(), "::deleteSingleton()");
+                logdebugs("calling ", name.c_str(), "::deleteSingleton()");
                 // From this point on, DO NOT DEREFERENCE sp!
                 sp->mDeleteSingleton();
             }
@@ -331,6 +361,12 @@ void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc)
 
 /*---------------------------- Logging helpers -----------------------------*/
 namespace {
+bool oktolog()
+{
+    // See comments in log() below.
+    return sMasterRefcount.refcount && LLError::is_available();
+}
+
 void log(LLError::ELevel level,
          const char* p1, const char* p2, const char* p3, const char* p4)
 {
@@ -362,6 +398,11 @@ void log(LLError::ELevel level,
         std::cerr << p1 << p2 << p3 << p4 << std::endl;
     }
 }
+
+void logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
+{
+    log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
+}
 } // anonymous namespace        
 
 //static
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 6a7f27bed45ac27b64b3295a02eaf71066ae62cb..78092fdc11951d7677bf2ce2761e8fc8235d74d4 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -66,8 +66,10 @@ class LLSingletonBase: private boost::noncopyable
     } EInitState;
 
     // Base-class constructor should only be invoked by the DERIVED_TYPE
-    // constructor.
-    LLSingletonBase();
+    // constructor, which passes the DERIVED_TYPE class name for logging
+    // purposes. Within LLSingletonBase::LLSingletonBase, of course the
+    // formula typeid(*this).name() produces "LLSingletonBase".
+    LLSingletonBase(const char* name);
     virtual ~LLSingletonBase();
 
     // Every new LLSingleton should be added to/removed from the master list
@@ -87,11 +89,15 @@ class LLSingletonBase: private boost::noncopyable
     // single C++ scope, else we'd use RAII to track it. But we do know that
     // LLSingletonBase's constructor definitely runs just before
     // LLSingleton's, which runs just before the specific subclass's.
-    void push_initializing();
+    void push_initializing(const char*);
     // LLSingleton is, and must remain, the only caller to initSingleton().
     // That being the case, we control exactly when it happens -- and we can
     // pop the stack immediately thereafter.
     void pop_initializing();
+private:
+    // logging
+    static void log_initializing(const char* verb, const char* name);
+protected:
     // If a given call to B::getInstance() happens during either A::A() or
     // A::initSingleton(), record that A directly depends on B.
     void capture_dependency(EInitState);
@@ -281,7 +287,9 @@ class LLSingleton : public LLSingletonBase
     };
 
 protected:
-    LLSingleton()
+    // Use typeid(DERIVED_TYPE) rather than typeid(*this) because, until our
+    // constructor completes, *this isn't yet a full-fledged DERIVED_TYPE.
+    LLSingleton(): LLSingletonBase(typeid(DERIVED_TYPE).name())
     {
         // populate base-class function pointer with the static
         // deleteSingleton() function for this particular specialization