diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index cd837c086789681a5ac78c6e55324e1f9e3d31ba..d6232d771d1e9f80328269752b7b10c1c7ee88d9 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -88,6 +88,9 @@ Recording::~Recording()
 	disclaim_alloc(gTraceMemStat, this);
 	disclaim_alloc(gTraceMemStat, mBuffers);
 
+	// allow recording destruction without thread recorder running, 
+	// otherwise thread shutdown could crash if a recording outlives the thread recorder
+	// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
 	if (isStarted() && LLTrace::get_thread_recorder().notNull())
 	{
 		LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
@@ -101,7 +104,10 @@ void Recording::update()
 	{
 		mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
 
-		llassert(mActiveBuffers);
+		// must have 
+		llassert(mActiveBuffers != NULL 
+				&& LLTrace::get_thread_recorder().notNull());
+
 		if(!mActiveBuffers->isCurrent())
 		{
 			AccumulatorBufferGroup* buffers = mBuffers.write();
@@ -125,12 +131,16 @@ void Recording::handleStart()
 {
 	mSamplingTimer.reset();
 	mBuffers.setStayUnique(true);
+	// must have thread recorder running on this thread
+	llassert(LLTrace::get_thread_recorder().notNull());
 	mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
 }
 
 void Recording::handleStop()
 {
 	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+	// must have thread recorder running on this thread
+	llassert(LLTrace::get_thread_recorder().notNull());
 	LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
 	mActiveBuffers = NULL;
 	mBuffers.setStayUnique(false);
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index a14a8ff035fc3e0943af3af335a65e5594ee150c..187d8546d386eb5f57fe8999c5950cd4812ab598 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -191,25 +191,25 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate(
 void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording )
 {
 	active_recording_list_t::iterator recording_it = bringUpToDate(recording);
-	if (recording_it != mActiveRecordings.end())
+	// this method should only be called on a thread where the recorder is active
+	llassert_always(recording_it != mActiveRecordings.end());
+
+	ActiveRecording* recording_to_remove = *recording_it;
+	bool was_current = recording_to_remove->mPartialRecording.isCurrent();
+	llassert(recording_to_remove->mTargetRecording == recording);
+	mActiveRecordings.erase(recording_it);
+	if (was_current)
 	{
-		ActiveRecording* recording_to_remove = *recording_it;
-		bool was_current = recording_to_remove->mPartialRecording.isCurrent();
-		llassert(recording_to_remove->mTargetRecording == recording);
-		mActiveRecordings.erase(recording_it);
-		if (was_current)
+		if (mActiveRecordings.empty())
 		{
-			if (mActiveRecordings.empty())
-			{
-				AccumulatorBufferGroup::clearCurrent();
-			}
-			else
-			{
-				mActiveRecordings.back()->mPartialRecording.makeCurrent();
-			}
+			AccumulatorBufferGroup::clearCurrent();
+		}
+		else
+		{
+			mActiveRecordings.back()->mPartialRecording.makeCurrent();
 		}
-		delete recording_to_remove;
 	}
+	delete recording_to_remove;
 }
 
 ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target )