diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index 55d0c85cbd051cb5a83fd573eac36e46291c2363..e1876599fccbc6a3154c5d1da5c7caf38ceda3ef 100644
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
@@ -29,9 +29,25 @@
 
 #include "llerror.h"
 
+#if LL_REF_COUNT_DEBUG
+#include "llthread.h"
+#include "llapr.h"
+#endif
+
 LLRefCount::LLRefCount(const LLRefCount& other)
 :	mRef(0)
 {
+#if LL_REF_COUNT_DEBUG
+	if(gAPRPoolp)
+	{
+		mMutexp = new LLMutex(gAPRPoolp) ;
+	}
+	else
+	{
+		mMutexp = NULL ;
+	}
+	mCrashAtUnlock = FALSE ;
+#endif
 }
 
 LLRefCount& LLRefCount::operator=(const LLRefCount&)
@@ -43,6 +59,17 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&)
 LLRefCount::LLRefCount() :
 	mRef(0)
 {
+#if LL_REF_COUNT_DEBUG
+	if(gAPRPoolp)
+	{
+		mMutexp = new LLMutex(gAPRPoolp) ;
+	}
+	else
+	{
+		mMutexp = NULL ;
+	}
+	mCrashAtUnlock = FALSE ;
+#endif
 }
 
 LLRefCount::~LLRefCount()
@@ -51,4 +78,87 @@ LLRefCount::~LLRefCount()
 	{
 		llerrs << "deleting non-zero reference" << llendl;
 	}
+
+#if LL_REF_COUNT_DEBUG
+	if(gAPRPoolp)
+	{
+		delete mMutexp ;
+	}
+#endif
 }
+
+#if LL_REF_COUNT_DEBUG
+void LLRefCount::ref() const
+{ 
+	if(mMutexp)
+	{
+		if(mMutexp->isLocked()) 
+		{
+			mCrashAtUnlock = TRUE ;
+			llerrs << "the mutex is locked by the thread: " << mLockedThreadID 
+				<< " Current thread: " << LLThread::currentID() << llendl ;
+		}
+
+		mMutexp->lock() ;
+		mLockedThreadID = LLThread::currentID() ;
+
+		mRef++; 
+
+		if(mCrashAtUnlock)
+		{
+			while(1); //crash here.
+		}
+		mMutexp->unlock() ;
+	}
+	else
+	{
+		mRef++; 
+	}
+} 
+
+S32 LLRefCount::unref() const
+{
+	if(mMutexp)
+	{
+		if(mMutexp->isLocked()) 
+		{
+			mCrashAtUnlock = TRUE ;
+			llerrs << "the mutex is locked by the thread: " << mLockedThreadID 
+				<< " Current thread: " << LLThread::currentID() << llendl ;
+		}
+
+		mMutexp->lock() ;
+		mLockedThreadID = LLThread::currentID() ;
+		
+		llassert(mRef >= 1);
+		if (0 == --mRef) 
+		{
+			if(mCrashAtUnlock)
+			{
+				while(1); //crash here.
+			}
+			mMutexp->unlock() ;
+
+			delete this; 
+			return 0;
+		}
+
+		if(mCrashAtUnlock)
+		{
+			while(1); //crash here.
+		}
+		mMutexp->unlock() ;
+		return mRef;
+	}
+	else
+	{
+		llassert(mRef >= 1);
+		if (0 == --mRef) 
+		{
+			delete this; 
+			return 0;
+		}
+		return mRef;
+	}
+}	
+#endif
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 19f008b15ccf43af020492d6c51108ffe4d45a96..693c1c4b833bd68e1b71f92178a6c06a873760bb 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -28,6 +28,11 @@
 
 #include <boost/noncopyable.hpp>
 
+#define LL_REF_COUNT_DEBUG 0
+#if LL_REF_COUNT_DEBUG
+class LLMutex ;
+#endif
+
 //----------------------------------------------------------------------------
 // RefCount objects should generally only be accessed by way of LLPointer<>'s
 // see llthread.h for LLThreadSafeRefCount
@@ -43,12 +48,16 @@ class LL_COMMON_API LLRefCount
 public:
 	LLRefCount();
 
-	void ref() const
+#if LL_REF_COUNT_DEBUG
+	void ref() const ;
+	S32 unref() const ;
+#else
+	inline void LLRefCount::ref() const
 	{ 
 		mRef++; 
 	} 
 
-	S32 unref() const
+	inline S32 LLRefCount::unref() const
 	{
 		llassert(mRef >= 1);
 		if (0 == --mRef) 
@@ -58,6 +67,7 @@ class LL_COMMON_API LLRefCount
 		}
 		return mRef;
 	}	
+#endif
 
 	//NOTE: when passing around a const LLRefCount object, this can return different results
 	// at different types, since mRef is mutable
@@ -68,6 +78,12 @@ class LL_COMMON_API LLRefCount
 
 private: 
 	mutable S32	mRef; 
+
+#if LL_REF_COUNT_DEBUG
+	LLMutex*  mMutexp ;
+	mutable U32  mLockedThreadID ;
+	mutable BOOL mCrashAtUnlock ; 
+#endif
 };
 
 #endif