Commit f592a96f authored by BRAMAS Berenger's avatar BRAMAS Berenger

add signal handler and a compilation option to get it

parent 94dfd88a
......@@ -68,6 +68,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/CMakeModules/morse/")
option( SCALFMM_USE_MEM_STATS "Set to ON to profile memory" OFF )
option( SCALFMM_ATTACHE_SOURCE "Set to ON to compile with -g" OFF )
option( SCALFMM_USE_ADDONS "Set to ON to compile add ons" OFF )
option( SCALFMM_USE_SIGNALS "Set to ON to catch various signal an print backtrace" OFF )
if( APPLE ) # to fix problem with GCC and avx
CMAKE_DEPENDENT_OPTION( SCALFMM_USE_SSE "Set to ON to compile with SSE support (and use intrinsec SSE P2P)" ON "CPUOPTION_SSE3;NOT CPUOPTION_AVX2" OFF )
CMAKE_DEPENDENT_OPTION( SCALFMM_USE_AVX "Set to ON to compile with AVX support (and use intrinsec AVX P2P)" OFF "CPUOPTION_AVX; NOT CPUOPTION_AVX2" OFF )
......@@ -679,6 +680,18 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/CMakeModules/morse/")
endif(PKG_CONFIG_FOUND)
endif(SCALFMM_USE_EZTRACE)
##################################################################
#
# To catch signals
#
##################################################################
if((WIN32 OR (${CMAKE_SYSTEM_NAME} MATCHES "Windows")) AND SCALFMM_USE_SIGNALS)
# We are on Windows and we cannot catch signals
message( FATAL_ERROR "Catching the signals requieres an UNIX system." )
else()
SET(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS} -rdynamic")
endif()
##################################################################
# #
# END SETTING VARIABLES #
......
......@@ -137,6 +137,12 @@ const std::string SCALFMMCompileLibs("@SCALFMM_COMPILE_LIBS@");
#cmakedefine SCALFMM_TIME_OMPTASKS
///////////////////////////////////////////////////////
// To catch signals and print backtrace
///////////////////////////////////////////////////////
#cmakedefine SCALFMM_USE_SIGNALS
///////////////////////////////////////////////////////
// To control starpu config
///////////////////////////////////////////////////////
......
/**
* @file
* This file contains the signal handler core functions.
* It installs handlers and catch signals.
* If backtrace is set to on during compilation then
* the trace is print when a signal is caught.
*/
#include "FGlobal.hpp"
#include "FSignalHandler.h"
//< Singleton/Controler of the signal system.
FSignalHandler FSignalHandler::controler;
#ifdef SCALFMM_USE_SIGNALS
#include "FLog.hpp"
#include <iostream>
#include <execinfo.h>
#include <cstdio>
#include <unistd.h>
#include <csignal>
#include <unistd.h>
#include <iostream>
/**
* @brief f_sig_handler catch the system signals.
* @param signalReceived
*/
void f_sig_handler(int signalReceived){
std::cerr << "[SCALFMM] Signal " << signalReceived << " has been intercepted." << std::endl;
FSignalHandler::controler.intercept(signalReceived);
const int maxStackCalls = 40;
void *stackArray[maxStackCalls];
const int callsToPrint = backtrace(stackArray, maxStackCalls);
backtrace_symbols_fd(stackArray, callsToPrint, STDERR_FILENO);
exit(signalReceived);
}
/**
* @brief f_install_signal_handler
* This install several handler for various signals.
*/
bool f_install_signal_handler(){
// The SIGINT signal is sent to a process by its controlling terminal when a user wishes to interrupt the process
if( signal(SIGINT, f_sig_handler) == SIG_ERR ){
FLOG( std::cout << "Signal Handler: Cannot install signal SIGINT\n"; )
}
// The SIGTERM signal is sent to a process to request its termination
if( signal(SIGTERM, f_sig_handler) == SIG_ERR ){
FLOG( std::cout << "Signal Handler: Cannot install signal SIGTERM\n"; )
}
// The SIGFPE signal is sent to a process when it executes an erroneous arithmetic operation, such as division by zero
if( signal(SIGFPE, f_sig_handler) == SIG_ERR ){
FLOG( std::cout << "Signal Handler: Cannot install signal SIGFPE\n"; )
}
// The SIGABRT signal is sent to a process to tell it to abort, i.e. to terminate
if( signal(SIGABRT, f_sig_handler) == SIG_ERR ){
FLOG( std::cout << "Signal Handler: Cannot install signal SIGABRT\n"; )
}
// The SIGSEGV signal is sent to a process when it makes an invalid virtual memory reference, or segmentation fault
if( signal(SIGSEGV, f_sig_handler) == SIG_ERR ){
FLOG( std::cout << "Signal Handler: Cannot install signal SIGSEGV\n"; )
}
return true;
}
#else
void f_sig_handler(int /*signalReceived*/){
}
bool f_install_signal_handler(){
return false;
}
#endif
#ifndef FSIGNALHANDLER_H
#define FSIGNALHANDLER_H
#include "FGlobal.hpp"
#include "FLog.hpp"
#include <functional>
#include <vector>
// Function in FSignalHandler.cpp
bool f_install_signal_handler();
class FSignalHandler
{
protected:
bool installed;
/** All callback to inform */
std::vector< std::function<void(int)> > callbacks;
/** Private constructor for singleton */
FSignalHandler() : installed(false){
installed = f_install_signal_handler();
}
/** A signal has been sent */
void intercept(const int signalReceived){
for(unsigned idx = 0 ; idx < callbacks.size() ; ++idx){
callbacks[idx](signalReceived);
}
}
friend void f_sig_handler(int signalReceived);
public:
/** Singleton */
static FSignalHandler controler;
~FSignalHandler(){
}
/** Add a callback to the listeners list */
void registerCallback(std::function<void(int)> aCallback){
callbacks.push_back(aCallback);
}
/** Remove some listeners */
void unregisterCallback(std::function<void(int)> aCallback){
using fptr = void(*)(int);
unsigned idx = 0 ;
for(; idx < callbacks.size() && !(callbacks[idx].target<fptr>() == aCallback.target<fptr>()); ++idx){
}
unsigned idxCopy = idx;
idx += 1;
for(; idx < callbacks.size() ; ++idx){
if(!(callbacks[idx].target<fptr>() == aCallback.target<fptr>())){
callbacks[idxCopy++] = callbacks[idx];
}
}
callbacks.resize(callbacks.size() - idxCopy);
}
bool isInstalled(){
return installed;
}
};
#endif // FSIGNALHANDLER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment