From 65df2738f37280c4ee9be52e578555568379035e Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Mon, 8 Feb 2021 11:20:57 +0100 Subject: [PATCH 1/3] Handling of SIGINT (Ctrl-C): Install signal handler via SetFatalHandler from CoreDumpSvc. Raise SIGKILL to avoid time-consuming stack-trace. --- Control/AthenaServices/src/CoreDumpSvc.h | 5 +++-- Control/AthenaServices/src/SetFatalHandler.cxx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Control/AthenaServices/src/CoreDumpSvc.h b/Control/AthenaServices/src/CoreDumpSvc.h index 92f671e3c345..b90986ec700c 100644 --- a/Control/AthenaServices/src/CoreDumpSvc.h +++ b/Control/AthenaServices/src/CoreDumpSvc.h @@ -114,9 +114,10 @@ private: Gaudi::Property<std::string> m_coreDumpStream{this, "CoreDumpStream", "stdout", "Stream to use for core dump [stdout,stderr]"}; - Gaudi::Property<int> m_fatalHandlerFlags{this, "FatalHandler", 0, + Gaudi::Property<int> m_fatalHandlerFlags{this, "FatalHandler", -1, "Flags given to the fatal handler this service installs\n" - "if the flag is zero, no additional fatal handler is installed"}; + "if the flag is zero, no additional fatal handler is installed.\n" + "-1 handles SIGINT (Ctrl-C)"}; Gaudi::Property<double> m_timeout{this, "TimeOut", 30.0*60*1e9, "Terminate job after it this reaches the time out in Wallclock time, " diff --git a/Control/AthenaServices/src/SetFatalHandler.cxx b/Control/AthenaServices/src/SetFatalHandler.cxx index 57963956bf14..2810cc676360 100644 --- a/Control/AthenaServices/src/SetFatalHandler.cxx +++ b/Control/AthenaServices/src/SetFatalHandler.cxx @@ -39,7 +39,7 @@ namespace { // called on user ^C std::cout << std::endl; std::cerr << "Athena CRITICAL stopped by user interrupt\n"; - std::terminate(); + raise(SIGKILL); } } -- GitLab From a0d31da0896e7ec2859b7e5adf4da7a6ab9b629d Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Tue, 9 Feb 2021 09:36:07 +0100 Subject: [PATCH 2/3] CoreDumpSvc.cxx: Adjust log-output to avoid failure of log-diff'ing unit-tests --- Control/AthenaServices/src/CoreDumpSvc.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Control/AthenaServices/src/CoreDumpSvc.cxx b/Control/AthenaServices/src/CoreDumpSvc.cxx index 0d7682987ac3..09d7a28d9c6a 100644 --- a/Control/AthenaServices/src/CoreDumpSvc.cxx +++ b/Control/AthenaServices/src/CoreDumpSvc.cxx @@ -238,7 +238,9 @@ void CoreDumpSvc::propertyHandler(Gaudi::Details::PropertyBase& p) StatusCode CoreDumpSvc::initialize() { if (m_fatalHandlerFlags != 0) { - ATH_MSG_INFO("install f-a-t-a-l handler... (flag = " << m_fatalHandlerFlags.value() << ")"); + if (m_fatalHandlerFlags != -1) { + ATH_MSG_INFO("install f-a-t-a-l handler... (flag = " << m_fatalHandlerFlags.value() << ")"); + } AthenaServices::SetFatalHandler(m_fatalHandlerFlags); } -- GitLab From 13f97dc6bb621f9c70ffda8878d1846a570e00c3 Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Thu, 11 Feb 2021 09:57:39 +0100 Subject: [PATCH 3/3] Incorporate functionality of SetFataHandler into CoreDumpSvc. Remove SetFatalHandler.h/cxx --- Control/AthenaServices/src/CoreDumpSvc.cxx | 40 ++++++++++--- Control/AthenaServices/src/CoreDumpSvc.h | 8 ++- .../AthenaServices/src/SetFatalHandler.cxx | 60 ------------------- Control/AthenaServices/src/SetFatalHandler.h | 51 ---------------- 4 files changed, 37 insertions(+), 122 deletions(-) delete mode 100644 Control/AthenaServices/src/SetFatalHandler.cxx delete mode 100644 Control/AthenaServices/src/SetFatalHandler.h diff --git a/Control/AthenaServices/src/CoreDumpSvc.cxx b/Control/AthenaServices/src/CoreDumpSvc.cxx index 09d7a28d9c6a..e6f3b24546fb 100644 --- a/Control/AthenaServices/src/CoreDumpSvc.cxx +++ b/Control/AthenaServices/src/CoreDumpSvc.cxx @@ -27,7 +27,6 @@ // Package includes #include "CoreDumpSvc.h" -#include "SetFatalHandler.h" // ROOT includes #include "TSystem.h" @@ -51,10 +50,21 @@ #include "CxxUtils/SealDebug.h" #include "CxxUtils/read_athena_statm.h" - namespace { + inline static const std::string horizLine = std::string(85,'-')+'\n'; -} + + void ExitOnInt( int sig, siginfo_t*, void* ) { + if ( sig == SIGINT ) { + // called on user ^C + std::cout << std::endl; + std::cerr << "Athena CRITICAL stopped by user interrupt\n"; + raise(SIGKILL); + } + } + +} // unnamed namespace + /** * @brief Signal handler for CoreDumpSvc @@ -191,7 +201,7 @@ CoreDumpSvc::CoreDumpSvc( const std::string& name, ISvcLocator* pSvcLocator ) : m_fastStackTrace.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this); m_coreDumpStream.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this); m_fatalHandlerFlags.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this); - + m_killOnSigInt.declareUpdateHandler(&CoreDumpSvc::propertyHandler, this); // Allocate for 2 slots just for now. m_usrCoreDumps.resize(2); m_sysCoreDumps.resize(2); @@ -223,12 +233,23 @@ void CoreDumpSvc::propertyHandler(Gaudi::Details::PropertyBase& p) } else if ( p.name() == m_fatalHandlerFlags.name() ) { if (m_fatalHandlerFlags.fromString(p.toString()).isSuccess()) { if (m_fatalHandlerFlags != 0) { - AthenaServices::SetFatalHandler( m_fatalHandlerFlags ); + Athena::Signal::handleFatal(nullptr, IOFD_INVALID, nullptr, nullptr, m_fatalHandlerFlags); } } else { ATH_MSG_INFO("could not convert [" << p.toString() << "] to integer"); } } + else if (p.name() == m_killOnSigInt.name()) { + if (m_killOnSigInt.fromString(p.toString()).isSuccess()) { + if (m_killOnSigInt) { + ATH_MSG_DEBUG("Will kill job on SIGINT (Ctrl-C)"); + Athena::Signal::handle( SIGINT, ExitOnInt ); + } + } + else { + ATH_MSG_WARNING("Could not convert [" << p.toString() << "] to bool"); + } + } } @@ -238,12 +259,15 @@ void CoreDumpSvc::propertyHandler(Gaudi::Details::PropertyBase& p) StatusCode CoreDumpSvc::initialize() { if (m_fatalHandlerFlags != 0) { - if (m_fatalHandlerFlags != -1) { ATH_MSG_INFO("install f-a-t-a-l handler... (flag = " << m_fatalHandlerFlags.value() << ")"); - } - AthenaServices::SetFatalHandler(m_fatalHandlerFlags); + Athena::Signal::handleFatal(nullptr, IOFD_INVALID, nullptr, nullptr, m_fatalHandlerFlags); } + if (m_killOnSigInt) { + ATH_MSG_DEBUG("Will kill job on SIGINT (Ctrl-C)"); + Athena::Signal::handle( SIGINT, ExitOnInt ); + } + if ( installSignalHandler().isFailure() ) { ATH_MSG_ERROR ("Could not install signal handlers"); return StatusCode::FAILURE; diff --git a/Control/AthenaServices/src/CoreDumpSvc.h b/Control/AthenaServices/src/CoreDumpSvc.h index b90986ec700c..359db928f7f0 100644 --- a/Control/AthenaServices/src/CoreDumpSvc.h +++ b/Control/AthenaServices/src/CoreDumpSvc.h @@ -114,14 +114,16 @@ private: Gaudi::Property<std::string> m_coreDumpStream{this, "CoreDumpStream", "stdout", "Stream to use for core dump [stdout,stderr]"}; - Gaudi::Property<int> m_fatalHandlerFlags{this, "FatalHandler", -1, + Gaudi::Property<int> m_fatalHandlerFlags{this, "FatalHandler", 0, "Flags given to the fatal handler this service installs\n" - "if the flag is zero, no additional fatal handler is installed.\n" - "-1 handles SIGINT (Ctrl-C)"}; + "if the flag is zero, no additional fatal handler is installed."}; Gaudi::Property<double> m_timeout{this, "TimeOut", 30.0*60*1e9, "Terminate job after it this reaches the time out in Wallclock time, " "usually due to hanging during stack unwinding. Timeout given in nanoseconds despite seconds precision"}; + + Gaudi::Property<bool> m_killOnSigInt{this, "KillOnSigInt",true, "Terminate job on SIGINT (aka Ctrl-C)"}; + ///@} diff --git a/Control/AthenaServices/src/SetFatalHandler.cxx b/Control/AthenaServices/src/SetFatalHandler.cxx deleted file mode 100644 index 2810cc676360..000000000000 --- a/Control/AthenaServices/src/SetFatalHandler.cxx +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -//=================================================================== -// SetFatalHandler.cxx -//-------------------------------------------------------------------- -// -// Package : AthenaServices -// -// Description: use the SEAL fatal handler to fatalize SIG_INT. -// -// Author : Wim Lavrijsen -// History : -// +---------+----------------------------------------------+--------- -// | Date | Comment | Who -// +---------+----------------------------------------------+--------- -// | 02/10/05| Initial version | WL -// +---------+----------------------------------------------+--------- -// -//==================================================================== - - -// External -#include "CxxUtils/SealCommon.h" -#include "CxxUtils/SealSignal.h" - -// Standard -#include <exception> -#include <iostream> - -#include "SetFatalHandler.h" - -//- helper ------------------------------------------------------------------- -namespace { - - void ExitOnInt( int sig, siginfo_t*, void* ) { - if ( sig == SIGINT ) { - // called on user ^C - std::cout << std::endl; - std::cerr << "Athena CRITICAL stopped by user interrupt\n"; - raise(SIGKILL); - } - } - -} // unnamed namespace - - -//- public members ----------------------------------------------------------- -void AthenaServices::SetFatalHandler( int flags ) { - - if ( flags < 0 ) { - Athena::Signal::handle( SIGINT, ExitOnInt ); - } - else { - Athena::Signal::handleFatal(nullptr, IOFD_INVALID, nullptr, nullptr, flags ); - Athena::Signal::handle( SIGINT, ExitOnInt ); - } - -} diff --git a/Control/AthenaServices/src/SetFatalHandler.h b/Control/AthenaServices/src/SetFatalHandler.h deleted file mode 100644 index 4f43792777c7..000000000000 --- a/Control/AthenaServices/src/SetFatalHandler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef ATHENASERVICES_SETFATALHANDLER_H -#define ATHENASERVICES_SETFATALHANDLER_H -/** @file SetFatalHandler.h - * @brief change traceback handling. It is in principle not needed but - * the observation is that in most cases it helps recovering a meaningful - * trace back. - * - * @author Wim Lavrjisen - * - * $Id: SetFatalHandler.h,v 1.2 2007-06-16 00:55:22 calaf Exp $ - */ - -/** @class AthenaServices - * @brief FIXME should be namespace, but we need to access from python... - */ -class AthenaServices { -public: -/** @fn void AthenaServices::SetFatalHandler( int flags) - * @brief change traceback handling. It is in principle not needed but - * the observation is that in most cases it helps recovering a meaningful - * trace back. - * - * @details - * see http://cern.ch/seal/workbook/sealbase.html - * - * @param flags a bit field. For example (from RecExCommon_topOptions.py) - * @code - * gbl.AthenaServices.SetFatalHandler(438) - * @endcode - * sets on the flags marked with an x - * @code - USR1_DUMP_CORE = 1 - FATAL_ON_QUIT = 2 x - FATAL_ON_INT = 4 x - FATAL_DUMP_CORE = 8 - FATAL_DUMP_SIG = 16 x - FATAL_DUMP_STACK = 32 x - FATAL_DUMP_LIBS = 64 - FATAL_DUMP_CONTEXT = 128 x - FATAL_AUTO_EXIT = 256 x - * @endcode - * - */ - static void SetFatalHandler( int flags = -1 ); -}; - -#endif // !ATHENASERVICES_SETFATALHANDLER_H -- GitLab