Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ endif()
option(TRACY_STATIC "Whether to build Tracy as a static library" ${DEFAULT_STATIC})
option(TRACY_Fortran "Build Fortran bindings" OFF)
option(TRACY_LTO "Enable Link-Time optimization" OFF)
option(TRACY_UI_PROFILER "Whether to build Tracy UI Profiler" OFF)

if(TRACY_Fortran)
enable_language(Fortran)
Expand Down Expand Up @@ -142,6 +143,7 @@ set_option(TRACY_SYMBOL_OFFLINE_RESOLVE "Instead of full runtime symbol resoluti
set_option(TRACY_LIBBACKTRACE_ELF_DYNLOAD_SUPPORT "Enable libbacktrace to support dynamically loaded elfs in symbol resolution resolution after the first symbol resolve operation" OFF)
set_option(TRACY_DEBUGINFOD "Enable debuginfod support" OFF)
set_option(TRACY_IGNORE_MEMORY_FAULTS "Ignore instrumentation errors from memory free events that do not have a matching allocation" OFF)
set_option(TRACY_DEFAULT_MEMORY_PROFLER "Enable default memory profiler on supported platforms" OFF)

# advanced
set_option(TRACY_VERBOSE "[advanced] Verbose output from the profiler" OFF)
Expand Down Expand Up @@ -283,3 +285,7 @@ if(TRACY_CLIENT_PYTHON)

add_subdirectory(python)
endif()

if (TRACY_UI_PROFILER)
add_subdirectory(profiler)
endif()
1 change: 1 addition & 0 deletions cmake/server.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(TRACY_COMMON_DIR ${CMAKE_CURRENT_LIST_DIR}/../public/common)

set(TRACY_COMMON_SOURCES
../client/TracyAlloc.cpp
tracy_lz4.cpp
tracy_lz4hc.cpp
TracySocket.cpp
Expand Down
14 changes: 13 additions & 1 deletion public/TracyClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# pragma warning(push, 0)
#endif

#include "client/TracyAlloc.cpp"
#include "common/tracy_lz4.cpp"
#include "client/TracyProfiler.cpp"
#include "client/TracyCallstack.cpp"
Expand All @@ -28,7 +29,6 @@
#include "common/TracySocket.cpp"
#include "client/tracy_rpmalloc.cpp"
#include "client/TracyDxt1.cpp"
#include "client/TracyAlloc.cpp"
#include "client/TracyOverride.cpp"
#include "client/TracyKCore.cpp"

Expand All @@ -42,4 +42,16 @@
# pragma warning(pop)
#endif

# ifdef TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
class BlockMemoryProfileHooks
{
public:
~BlockMemoryProfileHooks()
{
++tracy::DirectAlloc::s_direct; // at exit the application will try to free the static objects memory
// which will be traced by tracy::Profiler::MemFreeCallstack which needs those static objects
}
};
static BlockMemoryProfileHooks __blockMemoryProfileHooks;
# endif
#endif
155 changes: 150 additions & 5 deletions public/client/TracyAlloc.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,109 @@
#include "../common/TracyAlloc.hpp"

#if defined( TRACY_DEFAULT_MEMORY_PROFLER )/* && defined( TRACY_ON_DEMAND )*/
# if __has_include( <dlfcn.h>)
# include "../client/TracyProfiler.hpp"
# include <dlfcn.h>
# define TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
# endif
#endif

#ifndef TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
namespace
{
auto _malloc = &malloc;
auto _free = &free;
auto _calloc = &calloc;
auto _realloc = &realloc;
} // namespace {
#else
namespace
{

inline void* _malloc( size_t size )
{
static auto malloc_ = reinterpret_cast<void* (*)( size_t )>( dlsym( RTLD_NEXT, "malloc" ) );
return malloc_( size );
}
inline void _free( void* ptr )
{
static auto free_ = reinterpret_cast<void ( * )( void* )>( dlsym( RTLD_NEXT, "free" ) );
free_( ptr );
}
inline void* _calloc( size_t nmemb, size_t size )
{
static auto calloc_ = reinterpret_cast<void* (*)( size_t, size_t )>( dlsym( RTLD_NEXT, "calloc" ) );
return calloc_( nmemb, size );
}

inline void* _realloc( void* ptr, size_t size )
{
static auto realloc_ = reinterpret_cast<void* (*)( void*, size_t )>( dlsym( RTLD_NEXT, "realloc" ) );
return realloc_( ptr, size );
}

} // namespace {

extern "C"
{
void* malloc( size_t size )
{
if( tracy::DirectAlloc::s_direct )
return _malloc( size );
tracy::DirectAlloc locker;
auto _ptr = _malloc( size );
tracy::Profiler::MemAllocCallstack( _ptr, size, 50, false );
return _ptr;
}

void free( void* ptr )
{
if( tracy::DirectAlloc::s_direct )
return _free( ptr );
tracy::DirectAlloc locker;
if( ptr )
tracy::Profiler::MemFreeCallstack( ptr, 50, false );
_free( ptr );
}

void* calloc( size_t nmemb, size_t size )
{
if( tracy::DirectAlloc::s_direct )
return _calloc( nmemb, size );
tracy::DirectAlloc locker;
auto _ptr = _calloc( nmemb, size );
tracy::Profiler::MemAllocCallstack( _ptr, nmemb * size, 50, false );
return _ptr;
}

void* realloc( void* ptr, size_t size )
{
if( tracy::DirectAlloc::s_direct )
return _realloc( ptr, size );
tracy::DirectAlloc locker;
if( ptr )
tracy::Profiler::MemFreeCallstack( ptr, 50, false );
auto _ptr = _realloc( ptr, size );
tracy::Profiler::MemAllocCallstack( _ptr, size, 50, false );
return _ptr;
}
} // extern "C" {
#endif

#ifdef TRACY_USE_RPMALLOC

#include <atomic>
# include <atomic>

#include "../common/TracyForceInline.hpp"
#include "../common/TracyYield.hpp"
# include "../common/TracyForceInline.hpp"
# include "../common/TracyYield.hpp"
#endif

namespace tracy
{

thread_local int DirectAlloc::s_direct = 0;

#ifdef TRACY_USE_RPMALLOC
extern thread_local bool RpThreadInitDone;
extern std::atomic<int> RpInitDone;
extern std::atomic<int> RpInitLock;
Expand All @@ -20,7 +114,11 @@ tracy_no_inline static void InitRpmallocPlumbing()
if( !done )
{
int expected = 0;
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) )
{
expected = 0;
YieldThread();
}
const auto done = RpInitDone.load( std::memory_order_acquire );
if( !done )
{
Expand All @@ -37,7 +135,54 @@ TRACY_API void InitRpmalloc()
{
if( !RpThreadInitDone ) InitRpmallocPlumbing();
}
#endif

TRACY_API void* tracy_malloc( size_t size )
{
# ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
return rpmalloc( size );
# else
return _malloc( size );
# endif
}

#endif
TRACY_API void* tracy_malloc_fast( size_t size )
{
# ifdef TRACY_USE_RPMALLOC
return rpmalloc( size );
# else
return _malloc( size );
# endif
}

TRACY_API void tracy_free( void* ptr )
{
# ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
rpfree( ptr );
# else
_free( ptr );
# endif
}

TRACY_API void tracy_free_fast( void* ptr )
{
# ifdef TRACY_USE_RPMALLOC
rpfree( ptr );
# else
_free( ptr );
# endif
}

TRACY_API void* tracy_realloc( void* ptr, size_t size )
{
# ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
return rprealloc( ptr, size );
# else
return _realloc( ptr, size );
# endif
}

} // namespace tracy
2 changes: 2 additions & 0 deletions public/client/TracyCallstack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern "C" const char* ___tracy_demangle( const char* mangled )
if( strlen( mangled ) > ___tracy_demangle_buffer_len ) return nullptr;
int status;
size_t len = ___tracy_demangle_buffer_len;
tracy::DirectAlloc lock;
return abi::__cxa_demangle( mangled, ___tracy_demangle_buffer, &len, &status );
}
#endif
Expand Down Expand Up @@ -865,6 +866,7 @@ size_t s_kernelSymCnt;

static void InitKernelSymbols()
{
tracy::DirectAlloc lock;
FILE* f = fopen( "/proc/kallsyms", "rb" );
if( !f ) return;
tracy::FastVector<KernelSymbol> tmpSym( 512 * 1024 );
Expand Down
2 changes: 1 addition & 1 deletion public/client/TracyCallstack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static tracy_force_inline void* Callstack( int32_t depth )
assert( depth >= 1 );

auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );

tracy::DirectAlloc lock;
#ifdef TRACY_LIBUNWIND_BACKTRACE
size_t num = unw_backtrace( (void**)(trace+1), depth );
#else
Expand Down
6 changes: 5 additions & 1 deletion public/client/TracyProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ struct MappingInfo {
// vector is sorted by ascending address too.
static std::vector<MappingInfo> ParseMappings()
{
tracy::DirectAlloc lock;
std::vector<MappingInfo> result;
FILE* file = fopen( "/proc/self/maps", "r" );
if( !file ) return result;
Expand Down Expand Up @@ -513,6 +514,7 @@ static uint32_t GetHex( char*& ptr, int skip )

static const char* GetHostInfo()
{
tracy::DirectAlloc lock;
static char buf[1024];
auto ptr = buf;
#if defined _WIN32
Expand Down Expand Up @@ -3889,7 +3891,8 @@ void Profiler::CalibrateDelay()

void Profiler::ReportTopology()
{
#ifndef TRACY_DELAYED_INIT
DirectAlloc lock;
# ifndef TRACY_DELAYED_INIT
struct CpuData
{
uint32_t package;
Expand Down Expand Up @@ -4183,6 +4186,7 @@ void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size )

void Profiler::HandleSourceCodeQuery( char* data, char* image, uint32_t id )
{
tracy::DirectAlloc lock;
bool ok = false;
FILE* f = fopen( data, "rb" );
if( f )
Expand Down
18 changes: 15 additions & 3 deletions public/client/TracyProfiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,16 +842,28 @@ class Profiler
enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
enum class ThreadCtxStatus { Same, Changed, ConnectionLost };

static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
static void LaunchWorker( void* ptr )
{
tracy::DirectAlloc lock;
( (Profiler*)ptr )->Worker();
}
void Worker();

#ifndef TRACY_NO_FRAME_IMAGE
static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
static void LaunchCompressWorker( void* ptr )
{
tracy::DirectAlloc lock;
( (Profiler*)ptr )->CompressWorker();
}
void CompressWorker();
#endif

#ifdef TRACY_HAS_CALLSTACK
static void LaunchSymbolWorker( void* ptr ) { ((Profiler*)ptr)->SymbolWorker(); }
static void LaunchSymbolWorker( void* ptr )
{
tracy::DirectAlloc lock;
( (Profiler*)ptr )->SymbolWorker();
}
void SymbolWorker();
void HandleSymbolQueueItem( const SymbolQueueItem& si );
#endif
Expand Down
1 change: 1 addition & 0 deletions public/client/TracySysPower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void SysPower::Tick()

void SysPower::ScanDirectory( const char* path, int parent )
{
tracy::DirectAlloc lock;
DIR* dir = opendir( path );
if( !dir ) return;
struct dirent* ent;
Expand Down
1 change: 1 addition & 0 deletions public/client/TracySysTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void SysTime::ReadTimes()

void SysTime::ReadTimes()
{
tracy::DirectAlloc lock;
uint64_t user, nice, system;
FILE* f = fopen( "/proc/stat", "r" );
if( f )
Expand Down
2 changes: 2 additions & 0 deletions public/client/TracySysTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ static uint64_t* GetCallstackBlock( uint64_t cnt, RingBuffer& ring, uint64_t off

void SysTraceWorker( void* ptr )
{
tracy::DirectAlloc lock;
ThreadExitHandler threadExitHandler;
SetThreadName( "Tracy Sampling" );
InitRpmalloc();
Expand Down Expand Up @@ -1397,6 +1398,7 @@ void SysTraceWorker( void* ptr )

void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name )
{
tracy::DirectAlloc lock;
FILE* f;
char fn[256];
sprintf( fn, "/proc/%" PRIu64 "/comm", thread );
Expand Down
10 changes: 6 additions & 4 deletions public/client/tracy_rpmalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2705,11 +2705,13 @@ rpmalloc_initialize(void) {

int
rpmalloc_initialize_config(const rpmalloc_config_t* config) {
if (_rpmalloc_initialized) {
rpmalloc_thread_initialize();
tracy::DirectAlloc lock;
if( _rpmalloc_initialized )
{
rpmalloc_thread_initialize();
return 0;
}
_rpmalloc_initialized = 1;
}
_rpmalloc_initialized = 1;

if (config)
memcpy(&_memory_config, config, sizeof(rpmalloc_config_t));
Expand Down
Loading