From 06766b3650ed3bfb5d9a96e4536ef0b75a185542 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 31 Jan 2024 14:41:57 +0100 Subject: [PATCH] Add option to Preferences to flush file loggers when a signal is triggered --- ApplicationExeCode/RiaMain.cpp | 16 +++++++++++ ApplicationExeCode/RiaMainTools.cpp | 28 +++++++++++++++++++ .../Application/RiaPreferences.cpp | 11 ++++++++ .../Application/RiaPreferences.h | 2 ++ .../Application/Tools/RiaFileLogger.cpp | 16 +++++++++++ .../Application/Tools/RiaFileLogger.h | 2 ++ 6 files changed, 75 insertions(+) diff --git a/ApplicationExeCode/RiaMain.cpp b/ApplicationExeCode/RiaMain.cpp index 7a55b2e288..aad55a4336 100644 --- a/ApplicationExeCode/RiaMain.cpp +++ b/ApplicationExeCode/RiaMain.cpp @@ -18,6 +18,7 @@ #include "RiaArgumentParser.h" #include "RiaMainTools.h" +#include "RiaPreferences.h" #ifdef ENABLE_GRPC #include "RiaGrpcConsoleApplication.h" @@ -39,6 +40,10 @@ #include #endif +#include + +void manageSegFailure( int signalCode ); + RiaApplication* createApplication( int& argc, char* argv[] ) { for ( int i = 1; i < argc; ++i ) @@ -109,6 +114,17 @@ int main( int argc, char* argv[] ) QLocale::setDefault( QLocale( QLocale::English, QLocale::UnitedStates ) ); setlocale( LC_NUMERIC, "C" ); + // Set up signal handlers + if ( RiaPreferences::current()->loggerTrapSignalAndFlush() ) + { + signal( SIGINT, manageSegFailure ); + signal( SIGILL, manageSegFailure ); + signal( SIGFPE, manageSegFailure ); + signal( SIGSEGV, manageSegFailure ); + signal( SIGTERM, manageSegFailure ); + signal( SIGABRT, manageSegFailure ); + } + // Handle the command line arguments. // Todo: Move to a one-shot timer, delaying the execution until we are inside the event loop. // The complete handling of the resulting ApplicationStatus must be moved along. diff --git a/ApplicationExeCode/RiaMainTools.cpp b/ApplicationExeCode/RiaMainTools.cpp index 4a2fdcded3..8f5700acbb 100644 --- a/ApplicationExeCode/RiaMainTools.cpp +++ b/ApplicationExeCode/RiaMainTools.cpp @@ -17,6 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaMainTools.h" +#include "RiaFileLogger.h" +#include "RiaLogging.h" #include "RiaRegressionTestRunner.h" #include "RiaSocketCommand.h" @@ -25,6 +27,32 @@ #include "cafPdmDefaultObjectFactory.h" #include "cafPdmUiFieldEditorHandle.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void manageSegFailure( int signalCode ) +{ + // Executing function here is not safe, but works as expected on Windows. Behavior on Linux is undefined, but will + // work in some cases. + // https://github.com/gabime/spdlog/issues/1607 + + auto loggers = RiaLogging::loggerInstances(); + + QString str = QString( "Segmentation fault. Signal code: %1" ).arg( signalCode ); + + for ( auto logger : loggers ) + { + if ( auto fileLogger = dynamic_cast( logger ) ) + { + fileLogger->error( str.toStdString().data() ); + + fileLogger->flush(); + } + } + + exit( 1 ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaPreferences.cpp b/ApplicationLibCode/Application/RiaPreferences.cpp index f44b089cd9..f935916aab 100644 --- a/ApplicationLibCode/Application/RiaPreferences.cpp +++ b/ApplicationLibCode/Application/RiaPreferences.cpp @@ -137,6 +137,7 @@ RiaPreferences::RiaPreferences() m_loggerFilename.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() ); CAF_PDM_InitField( &m_loggerFlushInterval, "loggerFlushInterval", 500, "Logging Flush Interval [ms]" ); + CAF_PDM_InitField( &m_loggerTrapSignalAndFlush, "loggerTrapSignalAndFlush", false, "Trap SIGNAL and Flush File Logs" ); CAF_PDM_InitField( &ssihubAddress, "ssihubAddress", QString( "http://" ), "SSIHUB Address" ); ssihubAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); @@ -478,6 +479,8 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* loggingGroup = uiOrdering.addNewGroup( "Logging" ); loggingGroup->add( &m_loggerFilename ); loggingGroup->add( &m_loggerFlushInterval ); + loggingGroup->add( &m_loggerTrapSignalAndFlush ); + m_loggerTrapSignalAndFlush.uiCapability()->setUiReadOnly( !m_loggerFilename().first ); m_loggerFlushInterval.uiCapability()->setUiReadOnly( !m_loggerFilename().first ); } else if ( RiaApplication::enableDevelopmentFeatures() && uiConfigName == RiaPreferences::tabNameSystem() ) @@ -971,6 +974,14 @@ int RiaPreferences::loggerFlushInterval() const return m_loggerFlushInterval(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaPreferences::loggerTrapSignalAndFlush() const +{ + return m_loggerTrapSignalAndFlush(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaPreferences.h b/ApplicationLibCode/Application/RiaPreferences.h index 03a8f7bc6e..96628784f7 100644 --- a/ApplicationLibCode/Application/RiaPreferences.h +++ b/ApplicationLibCode/Application/RiaPreferences.h @@ -119,6 +119,7 @@ class RiaPreferences : public caf::PdmObject QString loggerFilename() const; int loggerFlushInterval() const; + bool loggerTrapSignalAndFlush() const; RiaPreferencesGeoMech* geoMechPreferences() const; RiaPreferencesSummary* summaryPreferences() const; @@ -209,6 +210,7 @@ class RiaPreferences : public caf::PdmObject // Logging caf::PdmField> m_loggerFilename; caf::PdmField m_loggerFlushInterval; + caf::PdmField m_loggerTrapSignalAndFlush; // Surface Import caf::PdmField m_surfaceImportResamplingDistance; diff --git a/ApplicationLibCode/Application/Tools/RiaFileLogger.cpp b/ApplicationLibCode/Application/Tools/RiaFileLogger.cpp index cf56bdb91b..3200527fd0 100644 --- a/ApplicationLibCode/Application/Tools/RiaFileLogger.cpp +++ b/ApplicationLibCode/Application/Tools/RiaFileLogger.cpp @@ -83,6 +83,14 @@ class RiaFileLogger::Impl if ( m_spdlogger ) m_spdlogger->warn( message ); } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void flush() + { + if ( m_spdlogger ) m_spdlogger->flush(); + } + private: std::shared_ptr m_spdlogger; }; @@ -150,3 +158,11 @@ void RiaFileLogger::debug( const char* message ) { m_impl->debug( message ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaFileLogger::flush() +{ + if ( m_impl ) m_impl->flush(); +} diff --git a/ApplicationLibCode/Application/Tools/RiaFileLogger.h b/ApplicationLibCode/Application/Tools/RiaFileLogger.h index 268b0f5503..2506eb2282 100644 --- a/ApplicationLibCode/Application/Tools/RiaFileLogger.h +++ b/ApplicationLibCode/Application/Tools/RiaFileLogger.h @@ -37,6 +37,8 @@ class RiaFileLogger : public RiaLogger void info( const char* message ) override; void debug( const char* message ) override; + void flush(); + private: int m_logLevel;