From 30771bf7cb44fe5fee691100cab7a451f70df1d3 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sun, 29 Mar 2020 23:01:57 +0200 Subject: [PATCH] Gather failure data before terminating connection. --- server/TracyWorker.cpp | 123 +++++++++++++++++++++++++++++++++++++++++ server/TracyWorker.hpp | 6 ++ 2 files changed, 129 insertions(+) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 819b1603..8fbbde4b 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -2793,6 +2793,7 @@ void Worker::Exec() auto ev = (const QueueItem*)ptr; if( !DispatchProcess( *ev, ptr ) ) { + if( m_failure != Failure::None ) HandleFailure( ptr, end ); QueryTerminate(); goto close; } @@ -2878,6 +2879,127 @@ close: m_connected.store( false, std::memory_order_relaxed ); } +bool Worker::IsThreadStringRetrieved( uint64_t id ) +{ + const auto name = GetThreadName( m_failureData.thread ); + return strcmp( name, "???" ) != 0; +} + +bool Worker::IsSourceLocationRetrieved( int16_t srcloc ) +{ + auto& sl = GetSourceLocation( srcloc ); + auto func = GetString( sl.function ); + auto file = GetString( sl.file ); + return strcmp( func, "???" ) != 0 && strcmp( file, "???" ) != 0; +} + +bool Worker::HasAllFailureData() +{ + if( m_failureData.thread != 0 && !IsThreadStringRetrieved( m_failureData.thread ) ) return false; + if( m_failureData.srcloc != 0 && !IsSourceLocationRetrieved( m_failureData.srcloc ) ) return false; + return true; +} + +void Worker::HandleFailure( const char* ptr, const char* end ) +{ + if( HasAllFailureData() ) return; + for(;;) + { + while( ptr < end ) + { + auto ev = (const QueueItem*)ptr; + DispatchFailure( *ev, ptr ); + } + if( HasAllFailureData() ) return; + + { + std::lock_guard lock( m_netWriteLock ); + m_netWriteCnt++; + m_netWriteCv.notify_one(); + } + + while( !m_serverQueryQueue.empty() && m_serverQuerySpaceLeft > 0 ) + { + m_serverQuerySpaceLeft--; + const auto& query = m_serverQueryQueue.back(); + m_sock.Send( &query, ServerQueryPacketSize ); + m_serverQueryQueue.pop_back(); + } + + if( m_shutdown.load( std::memory_order_relaxed ) ) return; + + NetBuffer netbuf; + { + std::unique_lock lock( m_netReadLock ); + m_netReadCv.wait( lock, [this] { return !m_netRead.empty(); } ); + netbuf = m_netRead.front(); + m_netRead.erase( m_netRead.begin() ); + } + if( netbuf.bufferOffset < 0 ) return; + + ptr = m_buffer + netbuf.bufferOffset; + end = ptr + netbuf.size; + } +} + +void Worker::DispatchFailure( const QueueItem& ev, const char*& ptr ) +{ + if( ev.hdr.idx >= (int)QueueType::StringData ) + { + ptr += sizeof( QueueHeader ) + sizeof( QueueStringTransfer ); + if( ev.hdr.type == QueueType::FrameImageData || + ev.hdr.type == QueueType::SymbolCode ) + { + uint32_t sz; + memcpy( &sz, ptr, sizeof( sz ) ); + ptr += sizeof( sz ) + sz; + } + else + { + uint16_t sz; + memcpy( &sz, ptr, sizeof( sz ) ); + ptr += sizeof( sz ); + switch( ev.hdr.type ) + { + case QueueType::StringData: + AddString( ev.stringTransfer.ptr, ptr, sz ); + m_serverQuerySpaceLeft++; + break; + case QueueType::ThreadName: + AddThreadString( ev.stringTransfer.ptr, ptr, sz ); + m_serverQuerySpaceLeft++; + break; + case QueueType::PlotName: + case QueueType::FrameName: + case QueueType::ExternalName: + m_serverQuerySpaceLeft++; + break; + default: + break; + } + ptr += sz; + } + } + else + { + ptr += QueueDataSize[ev.hdr.idx]; + switch( ev.hdr.type ) + { + case QueueType::SourceLocation: + AddSourceLocation( ev.srcloc ); + m_serverQuerySpaceLeft++; + break; + case QueueType::CallstackFrameSize: + case QueueType::SymbolInformation: + case QueueType::ParamPingback: + m_serverQuerySpaceLeft++; + break; + default: + break; + } + } +} + void Worker::Query( ServerQuery type, uint64_t data, uint32_t extra ) { ServerQueryPacket query { type, data, extra }; @@ -4912,6 +5034,7 @@ bool Worker::ProcessMemFree( const QueueMemFree& ev ) { if( !m_ignoreMemFreeFaults ) { + CheckThreadString( ev.thread ); MemFreeFailure( ev.thread ); } return false; diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 9cd7317b..800cf2f4 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -685,6 +685,12 @@ private: void HandlePostponedPlots(); void HandlePostponedSamples(); + bool IsThreadStringRetrieved( uint64_t id ); + bool IsSourceLocationRetrieved( int16_t srcloc ); + bool HasAllFailureData(); + void HandleFailure( const char* ptr, const char* end ); + void DispatchFailure( const QueueItem& ev, const char*& ptr ); + StringLocation StoreString( const char* str, size_t sz ); const ContextSwitch* const GetContextSwitchDataImpl( uint64_t thread );