diff --git a/client/TracySysTrace.cpp b/client/TracySysTrace.cpp index b4bbf553..70ba412f 100644 --- a/client/TracySysTrace.cpp +++ b/client/TracySysTrace.cpp @@ -77,6 +77,14 @@ struct ThreadTrace uint32_t subProcessTag; }; +struct StackWalkEvent +{ + uint64_t eventTimeStamp; + uint32_t stackProcess; + uint32_t stackThread; + uint64_t stack[192]; +}; + void WINAPI EventRecordCallback( PEVENT_RECORD record ) { #ifdef TRACY_ON_DEMAND @@ -125,6 +133,24 @@ void WINAPI EventRecordCallback( PEVENT_RECORD record ) TracyLfqCommit; } break; + case 0xdef2fe46: // StackWalk Guid + if( hdr.EventDescriptor.Opcode == 32 ) + { + const auto sw = (const StackWalkEvent*)record->UserData; + if( sw->stackProcess == s_pid ) + { + const uint64_t sz = ( record->UserDataLength - 16 ) / 8; + auto trace = (uint64_t*)tracy_malloc( ( 1 + sz ) * sizeof( uint64_t ) ); + memcpy( trace, &sz, sizeof( uint64_t ) ); + memcpy( trace+1, sw->stack, sizeof( uint64_t ) * sz ); + TracyLfqPrepare( QueueType::CallstackSample ); + MemWrite( &item->callstackSample.time, sw->eventTimeStamp ); + MemWrite( &item->callstackSample.thread, (uint64_t)sw->stackThread ); + MemWrite( &item->callstackSample.ptr, (uint64_t)trace ); + TracyLfqCommit; + } + } + break; default: break; } diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index aab0ad77..6bb1e796 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -9,7 +9,7 @@ namespace tracy constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; } -enum : uint32_t { ProtocolVersion = 25 }; +enum : uint32_t { ProtocolVersion = 26 }; enum : uint32_t { BroadcastVersion = 0 }; using lz4sz_t = uint32_t; diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 7249c4dc..72a24ca8 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -20,6 +20,7 @@ enum class QueueType : uint8_t CallstackMemory, Callstack, CallstackAlloc, + CallstackSample, FrameImage, ZoneBegin, ZoneBeginCallstack, @@ -290,6 +291,13 @@ struct QueueCallstackAlloc uint64_t nativePtr; }; +struct QueueCallstackSample +{ + int64_t time; + uint64_t thread; + uint64_t ptr; +}; + struct QueueCallstackFrameSize { uint64_t ptr; @@ -406,6 +414,7 @@ struct QueueItem QueueCallstackMemory callstackMemory; QueueCallstack callstack; QueueCallstackAlloc callstackAlloc; + QueueCallstackSample callstackSample; QueueCallstackFrameSize callstackFrameSize; QueueCallstackFrame callstackFrame; QueueCrashReport crashReport; @@ -436,6 +445,7 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueCallstackMemory ), sizeof( QueueHeader ) + sizeof( QueueCallstack ), sizeof( QueueHeader ) + sizeof( QueueCallstackAlloc ), + sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), sizeof( QueueHeader ) + sizeof( QueueFrameImage ), sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack