Merge pull request #1215 from slomp/slomp/worker-thread-race

Fixed race condition around `s_sysTraceThread`
This commit is contained in:
Bartosz Taudul
2025-12-03 22:43:42 +01:00
committed by GitHub

View File

@@ -933,7 +933,7 @@ static Thread* s_symbolThread;
std::atomic<bool> s_symbolThreadGone { false };
#endif
#ifdef TRACY_HAS_SYSTEM_TRACING
static Thread* s_sysTraceThread = nullptr;
static std::atomic<Thread*> s_sysTraceThread = nullptr;
#endif
#if defined __linux__ && !defined TRACY_NO_CRASH_HANDLER
@@ -1177,27 +1177,29 @@ static void StartSystemTracing( int64_t& samplingPeriod )
// use TRACY_NO_SYS_TRACE=1 to force disabling sys tracing (even if available in the underlying system)
// as it can have significant impact on the size of the traces
const char* noSysTrace = GetEnvVar( "TRACY_NO_SYS_TRACE" );
const bool disableSystrace = (noSysTrace && noSysTrace[0] == '1');
const bool disableSystrace = ( noSysTrace && noSysTrace[0] == '1' );
if( disableSystrace )
{
TracyDebug("TRACY: Sys Trace was disabled by 'TRACY_NO_SYS_TRACE=1'\n");
TracyDebug( "TRACY: Sys Trace was disabled by 'TRACY_NO_SYS_TRACE=1'\n" );
}
else if( SysTraceStart( samplingPeriod ) )
{
s_sysTraceThread = (Thread*)tracy_malloc( sizeof( Thread ) );
new(s_sysTraceThread) Thread( SysTraceWorker, nullptr );
Thread* sysTraceThread = (Thread*)tracy_malloc( sizeof( Thread ) );
new( sysTraceThread ) Thread( SysTraceWorker, nullptr );
Thread* prev = s_sysTraceThread.exchange( sysTraceThread );
assert( prev == nullptr );
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
}
}
static void StopSystemTracing()
{
if( s_sysTraceThread )
Thread* sysTraceThread = s_sysTraceThread.exchange( nullptr );
if( sysTraceThread )
{
SysTraceStop();
s_sysTraceThread->~Thread();
tracy_free( s_sysTraceThread );
s_sysTraceThread = nullptr;
sysTraceThread->~Thread();
tracy_free( sysTraceThread );
}
}
#endif
@@ -2146,9 +2148,15 @@ void Profiler::Worker()
while( s_symbolThreadGone.load() == false ) { YieldThread(); }
#endif
// Client is exiting.
#ifdef TRACY_HAS_SYSTEM_TRACING
// Stop filling queues with new data.
// On a typical shutdown scenario, the (global) Profiler object is destroyed by
// the C++ runtime when the client program returns from "main", and ~Profiler()
// takes care of calling StopSystemTracing(). However, a client may decide to
// manually RequestShutdown(), in which case ~Profile() may not execute before
// this Worker() thread goes through its teardown stages and reaches this point.
// To ensure that system tracing does not keep pushing data to the worker queue
// indefinitely (thus preventing this worker from terminating), we have to call
// StopSystemTracing() here as well to be safe:
StopSystemTracing();
#endif