From 094be55320959a18ca3d708019bde0b6ecacd39a Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Wed, 4 Nov 2026 19:05:25 +0100 Subject: [PATCH] Handle system time sampling failures safely. --- public/client/TracySysTime.cpp | 55 +++++++++++++++++++++------------- public/client/TracySysTime.hpp | 5 ++-- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/public/client/TracySysTime.cpp b/public/client/TracySysTime.cpp index 0a385002..c0e9a6cb 100644 --- a/public/client/TracySysTime.cpp +++ b/public/client/TracySysTime.cpp @@ -26,7 +26,7 @@ static inline uint64_t ConvertTime( const FILETIME& t ) return ( uint64_t( t.dwHighDateTime ) << 32 ) | uint64_t( t.dwLowDateTime ); } -void SysTime::ReadTimes() +bool SysTime::ReadTimes() { FILETIME kernelTime; FILETIME userTime; @@ -35,13 +35,13 @@ void SysTime::ReadTimes() FILETIME creationTime; FILETIME exitTime; - GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime ); + if( !GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime ) ) return false; idle = 0; # else FILETIME idleTime; - GetSystemTimes( &idleTime, &kernelTime, &userTime ); + if( !GetSystemTimes( &idleTime, &kernelTime, &userTime ) ) return false; idle = ConvertTime( idleTime ); # endif @@ -49,52 +49,58 @@ void SysTime::ReadTimes() const auto kernel = ConvertTime( kernelTime ); const auto user = ConvertTime( userTime ); used = kernel + user; + return true; } # elif defined __linux__ -void SysTime::ReadTimes() +bool SysTime::ReadTimes() { - uint64_t user, nice, system; + uint64_t user, nice, system, idleTicks; FILE* f = fopen( "/proc/stat", "r" ); - if( f ) - { - int read = fscanf( f, "cpu %" PRIu64 " %" PRIu64 " %" PRIu64" %" PRIu64, &user, &nice, &system, &idle ); - fclose( f ); - if (read == 4) - { - used = user + nice + system; - } - } + if( !f ) return false; + + const int read = fscanf( f, "cpu %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, &user, &nice, &system, &idleTicks ); + fclose( f ); + if( read != 4 ) return false; + + used = user + nice + system; + idle = idleTicks; + return true; } # elif defined __APPLE__ -void SysTime::ReadTimes() +bool SysTime::ReadTimes() { host_cpu_load_info_data_t info; mach_msg_type_number_t cnt = HOST_CPU_LOAD_INFO_COUNT; - host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast( &info ), &cnt ); + if( host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast( &info ), &cnt ) != KERN_SUCCESS ) return false; used = info.cpu_ticks[CPU_STATE_USER] + info.cpu_ticks[CPU_STATE_NICE] + info.cpu_ticks[CPU_STATE_SYSTEM]; idle = info.cpu_ticks[CPU_STATE_IDLE]; + return true; } # elif defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __DragonFly__ -void SysTime::ReadTimes() +bool SysTime::ReadTimes() { u_long data[5]; size_t sz = sizeof( data ); - sysctlbyname( "kern.cp_time", &data, &sz, nullptr, 0 ); + if( sysctlbyname( "kern.cp_time", &data, &sz, nullptr, 0 ) != 0 ) return false; used = data[0] + data[1] + data[2] + data[3]; idle = data[4]; + return true; } #endif SysTime::SysTime() + : idle( 0 ) + , used( 0 ) + , haveBaseline( false ) { - ReadTimes(); + haveBaseline = ReadTimes(); } float SysTime::Get() @@ -102,7 +108,16 @@ float SysTime::Get() const auto oldUsed = used; const auto oldIdle = idle; - ReadTimes(); + if( !ReadTimes() ) + { + haveBaseline = false; + return -1; + } + else if( !haveBaseline ) + { + haveBaseline = true; + return -1; + } const auto diffIdle = idle - oldIdle; const auto diffUsed = used - oldUsed; diff --git a/public/client/TracySysTime.hpp b/public/client/TracySysTime.hpp index 77dbd289..608e7b34 100644 --- a/public/client/TracySysTime.hpp +++ b/public/client/TracySysTime.hpp @@ -18,10 +18,11 @@ public: SysTime(); float Get(); - void ReadTimes(); - private: + bool ReadTimes(); + uint64_t idle, used; + bool haveBaseline; }; }