diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index f999d764..ae2b6eae 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -2130,7 +2130,8 @@ void Profiler::SendString( uint64_t str, const char* ptr, QueueType type ) void Profiler::SendLongString( uint64_t str, const char* ptr, size_t len, QueueType type ) { - assert( type == QueueType::FrameImageData ); + assert( type == QueueType::FrameImageData || + type == QueueType::SymbolCode ); QueueItem item; MemWrite( &item.hdr.type, type ); @@ -2354,6 +2355,9 @@ bool Profiler::HandleServerQuery() case ServerQuerySymbol: HandleSymbolQuery( ptr ); break; + case ServerQuerySymbolCode: + HandleSymbolCodeQuery( ptr, extra ); + break; default: assert( false ); break; @@ -2747,6 +2751,11 @@ void Profiler::HandleSymbolQuery( uint64_t symbol ) #endif } +void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size ) +{ + SendLongString( symbol, (const char*)symbol, size, QueueType::SymbolCode ); +} + } #ifdef __cplusplus diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index 3ab94726..ee6053e1 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -558,6 +558,7 @@ private: void HandleDisconnect(); void HandleParameter( uint64_t payload ); void HandleSymbolQuery( uint64_t symbol ); + void HandleSymbolCodeQuery( uint64_t symbol, uint32_t size ); void CalibrateTimer(); void CalibrateDelay(); diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index 80744c6a..35b98342 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -48,7 +48,8 @@ enum ServerQuery : uint8_t ServerQueryDisconnect, ServerQueryExternalName, ServerQueryParameter, - ServerQuerySymbol + ServerQuerySymbol, + ServerQuerySymbolCode }; struct ServerQueryPacket diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index b8726af2..416bea8f 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -83,6 +83,7 @@ enum class QueueType : uint8_t FrameImageData, ExternalName, ExternalThreadName, + SymbolCode, NUM_TYPES }; @@ -530,6 +531,7 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external name sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name + sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // symbol code }; static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" ); diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index bd166fbf..384f9bab 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -2761,7 +2761,7 @@ void Worker::Exec() if( m_pendingStrings != 0 || m_pendingThreads != 0 || m_pendingSourceLocation != 0 || m_pendingCallstackFrames != 0 || !m_pendingCustomStrings.empty() || m_data.plots.IsPending() || m_pendingCallstackPtr != 0 || m_pendingExternalNames != 0 || m_pendingCallstackSubframes != 0 || !m_pendingFrameImageData.empty() || - !m_pendingSymbols.empty() ) + !m_pendingSymbols.empty() || !m_pendingSymbolCode.empty() ) { continue; } @@ -2815,12 +2815,24 @@ bool Worker::DispatchProcess( const QueueItem& ev, const char*& ptr ) if( ev.hdr.idx >= (int)QueueType::StringData ) { ptr += sizeof( QueueHeader ) + sizeof( QueueStringTransfer ); - if( ev.hdr.type == QueueType::FrameImageData ) + if( ev.hdr.type == QueueType::FrameImageData || + ev.hdr.type == QueueType::SymbolCode ) { uint32_t sz; memcpy( &sz, ptr, sizeof( sz ) ); ptr += sizeof( sz ); - AddFrameImageData( ev.stringTransfer.ptr, ptr, sz ); + switch( ev.hdr.type ) + { + case QueueType::FrameImageData: + AddFrameImageData( ev.stringTransfer.ptr, ptr, sz ); + break; + case QueueType::SymbolCode: + AddSymbolCode( ev.stringTransfer.ptr, ptr, sz ); + break; + default: + assert( false ); + break; + } ptr += sz; } else @@ -3317,6 +3329,18 @@ void Worker::AddFrameImageData( uint64_t ptr, const char* data, size_t sz ) m_pendingFrameImageData.emplace( ptr, FrameImagePending { image, csz } ); } +void Worker::AddSymbolCode( uint64_t ptr, const char* data, size_t sz ) +{ + auto it = m_pendingSymbolCode.find( ptr ); + assert( it != m_pendingSymbolCode.end() ); + m_pendingSymbolCode.erase( it ); + + auto code = (char*)m_slab.AllocBig( sz ); + memcpy( code, data, sz ); + m_data.symbolCode.emplace( ptr, SymbolCodeData{ code, uint32_t( sz ) } ); + m_data.symbolCodeSize += sz; +} + uint64_t Worker::GetCanonicalPointer( const CallstackFrameId& id ) const { assert( id.sel == 0 ); @@ -5196,6 +5220,13 @@ void Worker::ProcessSymbolInformation( const QueueSymbolInformation& ev ) sd.size.SetVal( it->second.size ); m_data.symbolMap.emplace( ev.symAddr, std::move( sd ) ); + if( it->second.size > 0 && it->second.size <= 64*1024 ) + { + assert( m_pendingSymbolCode.find( ev.symAddr ) == m_pendingSymbolCode.end() ); + m_pendingSymbolCode.emplace( ev.symAddr ); + Query( ServerQuerySymbolCode, ev.symAddr, it->second.size ); + } + m_pendingSymbols.erase( it ); m_pendingCustomStrings.erase( fit ); } diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 9e5397c5..853fda6b 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -121,6 +121,12 @@ public: uint32_t core; }; + struct SymbolCodeData + { + const char* data; + uint32_t len; + }; + private: struct SourceLocationZones { @@ -283,6 +289,9 @@ private: unordered_flat_map>> cpuTopology; unordered_flat_map cpuTopologyMap; + + unordered_flat_map symbolCode; + uint64_t symbolCodeSize = 0; }; struct MbpsBlock @@ -654,6 +663,7 @@ private: void AddExternalName( uint64_t ptr, const char* str, size_t sz ); void AddExternalThreadName( uint64_t ptr, const char* str, size_t sz ); void AddFrameImageData( uint64_t ptr, const char* data, size_t sz ); + void AddSymbolCode( uint64_t ptr, const char* data, size_t sz ); tracy_force_inline void AddCallstackPayload( uint64_t ptr, const char* data, size_t sz ); tracy_force_inline void AddCallstackAllocPayload( uint64_t ptr, const char* data, size_t sz ); @@ -754,6 +764,7 @@ private: unordered_flat_map m_nextCallstack; unordered_flat_map m_pendingFrameImageData; unordered_flat_map m_pendingSymbols; + unordered_flat_set m_pendingSymbolCode; uint32_t m_pendingStrings; uint32_t m_pendingThreads;