From b2a8b53efa19fef63ef623bcdf8c251b7aeed08a Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Wed, 1 Apr 2020 21:43:03 +0200 Subject: [PATCH] Query source location of each assembly instruction. --- capture/build/unix/build.mk | 4 ++-- client/TracyProfiler.cpp | 22 +++++++++++++++++ client/TracyProfiler.hpp | 1 + common/TracyProtocol.hpp | 5 ++-- common/TracyQueue.hpp | 14 +++++++++-- import-chrome/build/unix/build.mk | 4 ++-- server/TracyWorker.cpp | 40 +++++++++++++++++++++++++++++++ update/build/unix/build.mk | 4 ++-- 8 files changed, 84 insertions(+), 10 deletions(-) diff --git a/capture/build/unix/build.mk b/capture/build/unix/build.mk index dec1c711..5378e008 100644 --- a/capture/build/unix/build.mk +++ b/capture/build/unix/build.mk @@ -1,8 +1,8 @@ CFLAGS += CXXFLAGS := $(CFLAGS) -std=gnu++17 DEFINES += -DTRACY_NO_STATISTICS -INCLUDES := -LIBS := -lpthread +INCLUDES := $(shell pkg-config --cflags capstone) +LIBS := $(shell pkg-config --libs capstone) -lpthread PROJECT := capture IMAGE := $(PROJECT)-$(BUILD) diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index bd6331b7..56c1423d 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -2373,6 +2373,9 @@ bool Profiler::HandleServerQuery() case ServerQuerySymbolCode: HandleSymbolCodeQuery( ptr, extra ); break; + case ServerQueryCodeLocation: + SendCodeLocation( ptr ); + break; default: assert( false ); break; @@ -2773,6 +2776,25 @@ void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size ) SendLongString( symbol, (const char*)symbol, size, QueueType::SymbolCode ); } +void Profiler::SendCodeLocation( uint64_t ptr ) +{ +#ifdef TRACY_HAS_CALLSTACK + const auto sym = DecodeCodeAddress( ptr ); + + SendString( uint64_t( sym.file ), sym.file, QueueType::CustomStringData ); + + QueueItem item; + MemWrite( &item.hdr.type, QueueType::CodeInformation ); + MemWrite( &item.codeInformation.ptr, ptr ); + MemWrite( &item.codeInformation.file, uint64_t( sym.file ) ); + MemWrite( &item.codeInformation.line, sym.line ); + + AppendData( &item, QueueDataSize[(int)QueueType::CodeInformation] ); + + if( sym.needFree ) tracy_free( (void*)sym.file ); +#endif +} + } #ifdef __cplusplus diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index ee6053e1..55e19c46 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -553,6 +553,7 @@ private: void SendCallstackPayload64( uint64_t ptr ); void SendCallstackAlloc( uint64_t ptr ); void SendCallstackFrame( uint64_t ptr ); + void SendCodeLocation( uint64_t ptr ); bool HandleServerQuery(); void HandleDisconnect(); diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index 3b7d3521..4dd9fa4f 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 = 29 }; +enum : uint32_t { ProtocolVersion = 30 }; enum : uint32_t { BroadcastVersion = 1 }; using lz4sz_t = uint32_t; @@ -50,7 +50,8 @@ enum ServerQuery : uint8_t ServerQueryExternalName, ServerQueryParameter, ServerQuerySymbol, - ServerQuerySymbolCode + ServerQuerySymbolCode, + ServerQueryCodeLocation }; struct ServerQueryPacket diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index b2c1b891..447c3afc 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -21,7 +21,6 @@ enum class QueueType : uint8_t Callstack, CallstackAlloc, CallstackSample, - SymbolInformation, FrameImage, ZoneBegin, ZoneBeginCallstack, @@ -67,6 +66,8 @@ enum class QueueType : uint8_t GpuNewContext, CallstackFrameSize, CallstackFrame, + SymbolInformation, + CodeInformation, SysTimeReport, TidToPid, PlotConfig, @@ -331,6 +332,13 @@ struct QueueSymbolInformation uint64_t symAddr; }; +struct QueueCodeInformation +{ + uint64_t ptr; + uint64_t file; + uint32_t line; +}; + struct QueueCrashReport { int64_t time; @@ -439,6 +447,7 @@ struct QueueItem QueueCallstackFrameSize callstackFrameSize; QueueCallstackFrame callstackFrame; QueueSymbolInformation symbolInformation; + QueueCodeInformation codeInformation; QueueCrashReport crashReport; QueueSysTime sysTime; QueueContextSwitch contextSwitch; @@ -468,7 +477,6 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueCallstack ), sizeof( QueueHeader ) + sizeof( QueueCallstackAlloc ), sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), - sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ), sizeof( QueueHeader ) + sizeof( QueueFrameImage ), sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack @@ -515,6 +523,8 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueGpuNewContext ), sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ), sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ), + sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ), + sizeof( QueueHeader ) + sizeof( QueueCodeInformation ), sizeof( QueueHeader ) + sizeof( QueueSysTime ), sizeof( QueueHeader ) + sizeof( QueueTidToPid ), sizeof( QueueHeader ) + sizeof( QueuePlotConfig ), diff --git a/import-chrome/build/unix/build.mk b/import-chrome/build/unix/build.mk index 27ac9f41..fcd1f6b0 100644 --- a/import-chrome/build/unix/build.mk +++ b/import-chrome/build/unix/build.mk @@ -1,8 +1,8 @@ CFLAGS += CXXFLAGS := $(CFLAGS) -std=gnu++17 DEFINES += -DTRACY_NO_STATISTICS -INCLUDES := -LIBS := -lpthread +INCLUDES := $(shell pkg-config --cflags capstone) +LIBS := $(shell pkg-config --libs capstone) -lpthread PROJECT := import-chrome IMAGE := $(PROJECT)-$(BUILD) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index e3049993..b8c7b189 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include "../common/TracyProtocol.hpp" #include "../common/TracySystem.hpp" #include "TracyFileRead.hpp" @@ -3559,6 +3561,40 @@ void Worker::AddSymbolCode( uint64_t ptr, const char* data, size_t sz ) memcpy( code, data, sz ); m_data.symbolCode.emplace( ptr, SymbolCodeData{ code, uint32_t( sz ) } ); m_data.symbolCodeSize += sz; + + if( m_data.cpuArch == CpuArchUnknown ) return; + csh handle; + cs_err rval = CS_ERR_ARCH; + switch( m_data.cpuArch ) + { + case CpuArchX86: + rval = cs_open( CS_ARCH_X86, CS_MODE_32, &handle ); + break; + case CpuArchX64: + rval = cs_open( CS_ARCH_X86, CS_MODE_64, &handle ); + break; + case CpuArchArm32: + rval = cs_open( CS_ARCH_ARM, CS_MODE_ARM, &handle ); + break; + case CpuArchArm64: + rval = cs_open( CS_ARCH_ARM64, CS_MODE_ARM, &handle ); + break; + default: + assert( false ); + break; + } + if( rval != CS_ERR_OK ) return; + cs_insn* insn; + size_t cnt = cs_disasm( handle, (const uint8_t*)code, sz, ptr, 0, &insn ); + if( cnt > 0 ) + { + for( size_t i=0; i