From e2d0db0617ba4250d30e9952395e91ddf18b2e0f Mon Sep 17 00:00:00 2001 From: Grant Karapetyan Date: Wed, 28 Sep 2022 17:02:11 +0400 Subject: [PATCH 1/2] Print active timer branch on crash --- source/MRMesh/MRLog.cpp | 3 +++ source/MRMesh/MRTimer.cpp | 47 ++++++++++++++++++++++++++++++------ source/MRMesh/MRTimer.h | 10 +++++--- source/MRViewer/MRViewer.cpp | 1 + 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/source/MRMesh/MRLog.cpp b/source/MRMesh/MRLog.cpp index 0bb33a8a0889..f03b16882108 100644 --- a/source/MRMesh/MRLog.cpp +++ b/source/MRMesh/MRLog.cpp @@ -3,6 +3,7 @@ #include "MRSystem.h" #include "MRStringConvert.h" #include "MRPch/MRSpdlog.h" +#include "MRTimer.h" #ifndef __EMSCRIPTEN__ #include @@ -35,6 +36,8 @@ void crashSignalHandler( int signal ) auto stacktrace = boost::stacktrace::stacktrace(); for ( const auto& frame : stacktrace ) spdlog::critical( "{} {} {}", frame.name(), frame.source_file(), frame.source_line() ); + + MR::printCurrentTimerBranch(); std::exit( signal ); } #endif diff --git a/source/MRMesh/MRTimer.cpp b/source/MRMesh/MRTimer.cpp index 3b306cc88516..275d7ecd7ff9 100644 --- a/source/MRMesh/MRTimer.cpp +++ b/source/MRMesh/MRTimer.cpp @@ -11,6 +11,7 @@ namespace MR struct TimeRecord { + TimeRecord* parent = nullptr; int count = 0; nanoseconds time = {}; std::map children; @@ -82,32 +83,64 @@ void printTimingTreeAtEnd( bool on ) rootTimeRecord.printTreeInDtor = on; } +void printCurrentTimerBranch() +{ + Timer t( "Print Timer branch leaf" ); + const TimeRecord* active = currentRecord; + auto& logger = rootTimeRecord.loggerHandle; + if ( !logger ) + return; + while ( active ) + { + if ( !active->parent ) + { + logger->info( "Root" ); + break; + } + for ( const auto& child : active->parent->children ) + { + if ( &child.second != active ) + continue; + logger->info( child.first ); + break; + } + active = active->parent; + } +} + void printTimingTreeAndStop() { rootTimeRecord.printTree(); printTimingTreeAtEnd( false ); } -void Timer::restart( std::string name ) +void Timer::restart( const std::string& name ) { finish(); + start( name ); +} + +void Timer::start( const std::string& name ) +{ if ( std::this_thread::get_id() != mainThreadId ) return; - name_ = std::move( name ); start_ = high_resolution_clock::now(); - parent_ = currentRecord; - currentRecord = ¤tRecord->children[name_]; + auto parent = currentRecord; + currentRecord = &parent->children[name]; + currentRecord->parent = parent; } void Timer::finish() { - if ( !parent_ ) + auto& currentParent = currentRecord->parent; + if ( !currentParent ) return; currentRecord->time += high_resolution_clock::now() - start_; ++currentRecord->count; - currentRecord = parent_; - parent_ = nullptr; + + currentRecord = currentParent; + currentParent = nullptr; } } //namespace MR diff --git a/source/MRMesh/MRTimer.h b/source/MRMesh/MRTimer.h index 2c91653b269c..a53633a784e6 100644 --- a/source/MRMesh/MRTimer.h +++ b/source/MRMesh/MRTimer.h @@ -15,10 +15,11 @@ struct TimeRecord; class Timer { public: - Timer( std::string name ) { restart( std::move( name ) ); } + Timer( const std::string& name ) { start( name ); } ~Timer() { finish(); } - MRMESH_API void restart( std::string name ); + MRMESH_API void restart( const std::string& name ); + MRMESH_API void start( const std::string& name ); MRMESH_API void finish(); Timer( const Timer & ) = delete; @@ -29,14 +30,15 @@ class Timer std::chrono::duration secondsPassed() const { return std::chrono::high_resolution_clock::now() - start_; } private: - TimeRecord * parent_ = nullptr; std::chrono::time_point start_; - std::string name_; }; /// enables or disables printing of timing tree when application terminates MRMESH_API void printTimingTreeAtEnd( bool on ); +/// prints current timer branch +MRMESH_API void printCurrentTimerBranch(); + /// prints the current timing tree, then calls printTimingTreeAtEnd( false ); MRMESH_API void printTimingTreeAndStop(); diff --git a/source/MRViewer/MRViewer.cpp b/source/MRViewer/MRViewer.cpp index 555a22f9edf9..16c5bdb0bfaa 100644 --- a/source/MRViewer/MRViewer.cpp +++ b/source/MRViewer/MRViewer.cpp @@ -227,6 +227,7 @@ int launchDefaultViewer( const Viewer::LaunchParams& params, const ViewerSetup& auto stacktrace = boost::stacktrace::stacktrace(); for ( const auto& frame : stacktrace ) spdlog::critical( "{} {} {}", frame.name(), frame.source_file(), frame.source_line() ); + printCurrentTimerBranch(); res = 1; } From 32c2a51d073f3d1693d9edda3d9a7b27655b15fb Mon Sep 17 00:00:00 2001 From: Grant Karapetyan Date: Wed, 28 Sep 2022 18:09:43 +0400 Subject: [PATCH 2/2] Fix UB --- source/MRMesh/MRTimer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/MRMesh/MRTimer.cpp b/source/MRMesh/MRTimer.cpp index 275d7ecd7ff9..e52370ac2959 100644 --- a/source/MRMesh/MRTimer.cpp +++ b/source/MRMesh/MRTimer.cpp @@ -132,7 +132,7 @@ void Timer::start( const std::string& name ) void Timer::finish() { - auto& currentParent = currentRecord->parent; + auto currentParent = currentRecord->parent; if ( !currentParent ) return; @@ -140,7 +140,6 @@ void Timer::finish() ++currentRecord->count; currentRecord = currentParent; - currentParent = nullptr; } } //namespace MR