SL-17868 Crash at ThreadRecorder::bringUpToDate

According to bugsplat get_thread_recorder was null
Replaced apr based LLThreadLocalPointer with thread_local
meow-7.2.2
Andrey Kleshchev 2022-07-30 01:36:56 +03:00
parent ebf7033f07
commit fe26a9d32c
10 changed files with 15 additions and 232 deletions

View File

@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp

View File

@ -30,7 +30,6 @@
#include "llapr.h"
#include "llmutex.h"
#include "apr_dso.h"
#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@ -54,7 +53,6 @@ void ll_init_apr()
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
LLThreadLocalPointerBase::initAllThreadLocalStorage();
gAPRInitialized = true;
}
@ -70,8 +68,6 @@ void ll_cleanup_apr()
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);

View File

@ -36,8 +36,6 @@
#include <boost/noncopyable.hpp>
#include "llwin32headerslean.h"
#include "apr_thread_proc.h"
#include "apr_getopt.h"
#include "apr_signal.h"
#include "llstring.h"

View File

@ -1,115 +0,0 @@
/**
* @file llthreadlocalstorage.cpp
* @author Richard
* @date 2013-1-11
* @brief implementation of thread local storage utility classes
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llthreadlocalstorage.h"
#include "llapr.h"
//
//LLThreadLocalPointerBase
//
bool LLThreadLocalPointerBase::sInitialized = false;
void LLThreadLocalPointerBase::set( void* value )
{
llassert(sInitialized && mThreadKey);
apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
}
}
void* LLThreadLocalPointerBase::get() const
{
// llassert(sInitialized);
void* ptr;
apr_status_t result =
apr_threadkey_private_get(&ptr, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
}
return ptr;
}
void LLThreadLocalPointerBase::initStorage( )
{
apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
}
}
void LLThreadLocalPointerBase::destroyStorage()
{
if (sInitialized)
{
if (mThreadKey)
{
apr_status_t result = apr_threadkey_private_delete(mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
}
}
}
}
//static
void LLThreadLocalPointerBase::initAllThreadLocalStorage()
{
if (!sInitialized)
{
for (auto& base : instance_snapshot())
{
base.initStorage();
}
sInitialized = true;
}
}
//static
void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
{
if (sInitialized)
{
//for (auto& base : instance_snapshot())
//{
// base.destroyStorage();
//}
sInitialized = false;
}
}

View File

@ -30,100 +30,6 @@
#include "llinstancetracker.h"
class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
{
public:
LLThreadLocalPointerBase()
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
~LLThreadLocalPointerBase()
{
destroyStorage();
}
static void initAllThreadLocalStorage();
static void destroyAllThreadLocalStorage();
protected:
void set(void* value);
void* get() const;
void initStorage();
void destroyStorage();
protected:
struct apr_threadkey_t* mThreadKey;
static bool sInitialized;
};
template <typename T>
class LLThreadLocalPointer : public LLThreadLocalPointerBase
{
public:
LLThreadLocalPointer()
{}
explicit LLThreadLocalPointer(T* value)
{
set(value);
}
LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
: LLThreadLocalPointerBase(other)
{
set(other.get());
}
LL_FORCE_INLINE T* get() const
{
return (T*)LLThreadLocalPointerBase::get();
}
T* operator -> () const
{
return (T*)get();
}
T& operator*() const
{
return *(T*)get();
}
LLThreadLocalPointer<T>& operator = (T* value)
{
set((void*)value);
return *this;
}
bool operator ==(const T* other) const
{
if (!sInitialized) return false;
return get() == other;
}
bool isNull() const { return !sInitialized || get() == NULL; }
bool notNull() const { return sInitialized && get() != NULL; }
};
template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
@ -139,10 +45,10 @@ public:
}
private:
static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
static thread_local DERIVED_TYPE* sInstance;
};
template<typename DERIVED_TYPE>
LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
#endif // LL_LLTHREADLOCALSTORAGE_H

View File

@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
mDescription(description ? description : "")
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLTrace::get_thread_recorder().notNull())
if (LLTrace::get_thread_recorder() != NULL)
{
LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL;
}

View File

@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
mStackTimers.makeCurrent();
mMemStats.makeCurrent();
ThreadRecorder* thread_recorder = get_thread_recorder().get();
ThreadRecorder* thread_recorder = get_thread_recorder();
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
// update stacktimer parent pointers
for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)

View File

@ -95,7 +95,7 @@ Recording::~Recording()
// 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())
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
{
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
}
@ -112,9 +112,9 @@ void Recording::update()
// must have
llassert(mActiveBuffers != NULL
&& LLTrace::get_thread_recorder().notNull());
&& LLTrace::get_thread_recorder() != NULL);
if(!mActiveBuffers->isCurrent())
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
{
AccumulatorBufferGroup* buffers = mBuffers.write();
LLTrace::get_thread_recorder()->deactivate(buffers);
@ -144,7 +144,7 @@ void Recording::handleStart()
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
#endif
}
@ -155,7 +155,7 @@ void Recording::handleStop()
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
mActiveBuffers = NULL;
mBuffers.setStayUnique(false);
@ -1181,8 +1181,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
PeriodicRecording& get_frame_recording()
{
static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
return *sRecording;
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
return sRecording;
}
}

View File

@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
return sMasterThreadRecorder;
}
LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
ThreadRecorder*& get_thread_recorder_ptr()
{
static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
static thread_local ThreadRecorder* s_thread_recorder;
return s_thread_recorder;
}
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
ThreadRecorder* get_thread_recorder()
{
return get_thread_recorder_ptr();
}

View File

@ -32,7 +32,6 @@
#include "llmutex.h"
#include "lltraceaccumulators.h"
#include "llthreadlocalstorage.h"
namespace LLTrace
{
@ -92,7 +91,7 @@ namespace LLTrace
};
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
ThreadRecorder* get_thread_recorder();
void set_thread_recorder(ThreadRecorder*);
void set_master_thread_recorder(ThreadRecorder*);