17#include "GaudiKernel/INamedInterface.h"
18#include "GaudiKernel/EventContext.h"
43 typedef std::lock_guard<std::mutex>
lock_t;
47#if defined(__linux__) && ( defined(__i386__) || defined(__x86_64__) )
63 ISvcLocator* pSvcLocator ) :
70 "Flag to configure, how many stack traces in case of FPE are printed. "
71 "Default: Zero, just report that FPE has happened. "
72 "After collecting the stacktrace, the code has to modify the mcontext_t "
73 "struct to ignore FPEs for the rest of the processing of the algorithm/service "
74 "This part is highly non-portable!" );
76 declareProperty(
"Nstacklines",
m_Nstacklines,
"Limit how deep we dive into the stack");
97 return StatusCode::SUCCESS;
113 return StatusCode::SUCCESS;
122 ATH_MSG_WARNING(
"Collecting stack traces for FPES is not supported on aarch64");
127 struct sigaction act;
128 memset(&act, 0,
sizeof act);
129 act.sa_sigaction = FPEAudit::fpe_sig_action;
130 act.sa_flags = SA_SIGINFO;
131 if ( sigaction(SIGFPE, &act, &FPEAudit::s_oldactHandler) != 0 )
133 ATH_MSG_WARNING (
"Printing stacktraces on FPE requested, but unable to install signal handler ! Switched off !");
139 FPEAudit::unmask_fpe();
154 feclearexcept(FE_ALL_EXCEPT);
156 FPEAudit::mask_fpe();
167 if ( event==IAuditor::Execute ) {
179 const EventContext& ctx,
const StatusCode&)
184 if ( event==IAuditor::Initialize ) {
199 const std::string& caller,
200 const EventContext& ctx)
203 int raised = fetestexcept(FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
205 std::stringstream evStr;
207 evStr <<
" on event " << ctx.eventID().event_number();
210 if (raised & FE_OVERFLOW) {
211 ATH_MSG_WARNING(
"FPE OVERFLOW in [" << step <<
"] of [" << caller <<
"]" << evStr.str() <<
221 this->
msg(MSG::INFO) <<
"FPE stacktrace " << j <<
" :\n";
228 if (raised & FE_INVALID) {
229 ATH_MSG_WARNING(
"FPE INVALID in [" << step <<
"] of [" << caller <<
"]" << evStr.str()
240 this->
msg(MSG::INFO) <<
"FPE stacktrace " << j <<
" :\n";
246 if (raised & FE_DIVBYZERO) {
247 ATH_MSG_WARNING(
"FPE DIVBYZERO in [" << step <<
"] of [" << caller <<
"]" << evStr.str()
257 this->
msg(MSG::INFO) <<
"FPE stacktrace " << j <<
" :\n";
271 fprintf(stderr,
"too many SIGFPE detected, will be uninstalling signal handler\n");
281 int raised = fetestexcept(FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
285 feclearexcept(FE_ALL_EXCEPT);
294 FPEAudit::mask_fpe();
303 throw std::runtime_error(
"inconsistent fpe-stack");
315 FPEAudit::unmask_fpe();
#define ATH_MSG_WARNING(x)
Define macros for attributes used to control the static checker.
std::atomic< int > m_nexceptions
unsigned int m_NstacktracesOnFPE
std::atomic< unsigned int > m_CountFPEs[FPEAUDITOR_ARRAYSIZE]
virtual StatusCode finalize() override
virtual void after(const std::string &event, const std::string &name, const EventContext &ctx, const StatusCode &sc) override
std::list< FpeNode_t > FpeStack_t
FPEAuditor(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
static thread_local FpeStack_t s_fpe_stack
a stack of FPE exceptions which have been raised
virtual void before(const std::string &event, const std::string &name, const EventContext &ctx) override
Auditor hooks.
virtual ~FPEAuditor()
Destructor.
void add_fpe_node()
add an fpe node
fenv_t m_env
The FP environment before we initialize.
virtual StatusCode initialize() override
Gaudi hooks.
void report_fpe(const std::string &step, const std::string &caller, const EventContext &ctx)
report fpes which happened during step 'step' on behalf of 'caller'
unsigned int m_Nstacklines
void pop_fpe_node()
pop an fpe node
thread_local FPEAuditTLSData s_tlsdata
std::lock_guard< std::mutex > lock_t
struct sigaction s_oldactHandler ATLAS_THREAD_SAFE
std::atomic< bool > s_handlerDisabled
std::atomic< bool > s_handlerInstalled
void * s_array_D[MAXARRAY]
void * s_array_O[MAXARRAY]
void * s_array_I[MAXARRAY]