ATLAS Offline Software
Loading...
Searching...
No Matches
FPEAuditor Class Reference

#include <FPEAuditor.h>

Inheritance diagram for FPEAuditor:
Collaboration diagram for FPEAuditor:

Public Member Functions

 FPEAuditor (const std::string &name, ISvcLocator *pSvcLocator)
 Constructor.
virtual ~FPEAuditor ()
 Destructor.
virtual StatusCode initialize () override
 Gaudi hooks.
virtual StatusCode finalize () override
virtual void before (const std::string &event, const std::string &name, const EventContext &ctx) override
 Auditor hooks.
virtual void after (const std::string &event, const std::string &name, const EventContext &ctx, const StatusCode &sc) override
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Private Types

enum  { FPEAUDITOR_OVERFLOW =0 , FPEAUDITOR_INVALID =1 , FPEAUDITOR_DIVBYZERO =2 , FPEAUDITOR_ARRAYSIZE =3 }

Private Member Functions

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'
void add_fpe_node ()
 add an fpe node
void pop_fpe_node ()
 pop an fpe node
void InstallHandler ()
void UninstallHandler ()

Private Attributes

std::atomic< unsigned int > m_CountFPEs [FPEAUDITOR_ARRAYSIZE]
unsigned int m_NstacktracesOnFPE =0
unsigned int m_Nstacklines =100
fenv_t m_env
 The FP environment before we initialize.
std::atomic< int > m_nexceptions

Detailed Description

Definition at line 33 of file FPEAuditor.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private
Enumerator
FPEAUDITOR_OVERFLOW 
FPEAUDITOR_INVALID 
FPEAUDITOR_DIVBYZERO 
FPEAUDITOR_ARRAYSIZE 

Definition at line 75 of file FPEAuditor.h.

Constructor & Destructor Documentation

◆ FPEAuditor()

FPEAuditor::FPEAuditor ( const std::string & name,
ISvcLocator * pSvcLocator )

Constructor.

Definition at line 60 of file FPEAuditor.cxx.

61 :
62 AthCommonMsg<Auditor> ( name, pSvcLocator ),
64 m_env(),
66{
67 declareProperty("NStacktracesOnFPE", m_NstacktracesOnFPE,
68 "Flag to configure, how many stack traces in case of FPE are printed. "
69 "Default: Zero, just report that FPE has happened. "
70 "After collecting the stacktrace, the code has to modify the mcontext_t "
71 "struct to ignore FPEs for the rest of the processing of the algorithm/service "
72 "This part is highly non-portable!" );
73
74 declareProperty("Nstacklines", m_Nstacklines,"Limit how deep we dive into the stack");
75}
std::atomic< int > m_nexceptions
Definition FPEAuditor.h:92
unsigned int m_NstacktracesOnFPE
Definition FPEAuditor.h:79
std::atomic< unsigned int > m_CountFPEs[FPEAUDITOR_ARRAYSIZE]
Definition FPEAuditor.h:77
fenv_t m_env
The FP environment before we initialize.
Definition FPEAuditor.h:90
unsigned int m_Nstacklines
Definition FPEAuditor.h:81

◆ ~FPEAuditor()

FPEAuditor::~FPEAuditor ( )
virtual

Destructor.

Definition at line 81 of file FPEAuditor.cxx.

82{
83 //m_msg << MSG::DEBUG << "Calling destructor" << endmsg;
84}

Member Function Documentation

◆ add_fpe_node()

void FPEAuditor::add_fpe_node ( )
private

add an fpe node

Definition at line 276 of file FPEAuditor.cxx.

277{
278 // clear FPE status word
279 feclearexcept(FE_ALL_EXCEPT);
280
282 // Make sure exceptions have been masked off if the handler has been
283 // disabled. Yes, this is already done in the signal handler.
284 // But when TBB starts a new task, it resets the FPU control words
285 // to values that were copied when the thread pool was initialized.
286 // FIXME: Do it properly with TBB? Not sure that the current
287 // interfaces allow it.
288 FPEAudit::mask_fpe();
289 }
290}
std::atomic< bool > s_handlerDisabled

◆ after()

void FPEAuditor::after ( const std::string & event,
const std::string & name,
const EventContext & ctx,
const StatusCode & sc )
overridevirtual

Definition at line 176 of file FPEAuditor.cxx.

178{
179 report_fpe(event, name, ctx);
180 pop_fpe_node();
181
182 if ( event==IAuditor::Initialize ) {
184 // CoreDumpSvc can also install a FPE handler, grrr.
185 if (name == "CoreDumpSvc") FPEAudit::s_handlerInstalled = false;
189 }
190 }
191}
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
void InstallHandler()
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'
void pop_fpe_node()
pop an fpe node
std::lock_guard< std::mutex > lock_t
std::mutex s_mutex
std::atomic< bool > s_handlerInstalled

◆ before()

void FPEAuditor::before ( const std::string & event,
const std::string & name,
const EventContext & ctx )
overridevirtual

Auditor hooks.

Definition at line 160 of file FPEAuditor.cxx.

162{
163 add_fpe_node();
164
165 if ( event==IAuditor::Execute ) {
171 }
172 }
173 }
174}
void add_fpe_node()
add an fpe node

◆ finalize()

StatusCode FPEAuditor::finalize ( )
overridevirtual

Definition at line 98 of file FPEAuditor.cxx.

99{
100 ATH_MSG_INFO("FPE summary for this job");
101 ATH_MSG_INFO(" FPE OVERFLOWs : " << m_CountFPEs[FPEAUDITOR_OVERFLOW] );
102 ATH_MSG_INFO(" FPE INVALIDs : " << m_CountFPEs[FPEAUDITOR_INVALID]);
103 ATH_MSG_INFO(" FPE DIVBYZEROs : " << m_CountFPEs[FPEAUDITOR_DIVBYZERO]);
104
105 {
109 }
110
111 return StatusCode::SUCCESS;
112}
#define ATH_MSG_INFO(x)
void UninstallHandler()

◆ initialize()

StatusCode FPEAuditor::initialize ( )
overridevirtual

Gaudi hooks.

Definition at line 86 of file FPEAuditor.cxx.

87{
88 for ( unsigned int i(0); i<FPEAUDITOR_ARRAYSIZE; ++i )
89 m_CountFPEs[i]=0;
90 //ATH_MSG_INFO("==> initialize");
91 // add a fake node here because we may come alive while the AuditorSvc is
92 // still initializing (so one edge is left orphaned)
94
95 return StatusCode::SUCCESS;
96}

◆ InstallHandler()

void FPEAuditor::InstallHandler ( )
private

Definition at line 114 of file FPEAuditor.cxx.

115{
116 // Save the current FP environment.
117 fegetenv (&m_env);
118
119#ifdef __aarch64__
120 ATH_MSG_WARNING("Collecting stack traces for FPES is not supported on aarch64");
124#else
125 struct sigaction act;
126 memset(&act, 0, sizeof act);
127 act.sa_sigaction = FPEAudit::fpe_sig_action;
128 act.sa_flags = SA_SIGINFO;
129 if ( sigaction(SIGFPE, &act, &FPEAudit::s_oldactHandler) != 0 )
130 {
131 ATH_MSG_WARNING ("Printing stacktraces on FPE requested, but unable to install signal handler ! Switched off !");
133 }
135 {
136 ATH_MSG_INFO ("Installed Signalhandler !");
137 FPEAudit::unmask_fpe();
138 }
142
144#endif
145}
#define ATH_MSG_WARNING(x)
FPEAuditTLSData s_tlsdata
void * s_array_D[MAXARRAY]
void * s_array_O[MAXARRAY]
void * s_array_I[MAXARRAY]

◆ msg()

MsgStream & AthCommonMsg< Gaudi::Auditor >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< Gaudi::Auditor >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ pop_fpe_node()

void FPEAuditor::pop_fpe_node ( )
private

pop an fpe node

Definition at line 293 of file FPEAuditor.cxx.

294{
296 FPEAudit::unmask_fpe();
297 }
298}

◆ report_fpe()

void FPEAuditor::report_fpe ( const std::string & step,
const std::string & caller,
const EventContext & ctx )
private

report fpes which happened during step 'step' on behalf of 'caller'

Definition at line 196 of file FPEAuditor.cxx.

199{
200 // store current list of FPE flags which were raised before
201 int raised = fetestexcept(FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
202 if (raised) {
203 std::stringstream evStr;
204 if (ctx.valid()) {
205 evStr << " on event " << ctx.eventID().event_number();
206 }
207
208 if (raised & FE_OVERFLOW) {
209 ATH_MSG_WARNING("FPE OVERFLOW in [" << step << "] of [" << caller << "]" << evStr.str() <<
211 );
213 if ( m_NstacktracesOnFPE && FPEAudit::s_tlsdata.s_array_O[0] != NULL )
214 {
215 for (unsigned int j = 0; j < m_Nstacklines; j++)
216 {
218 if (FPEAudit::s_tlsdata.s_array_O[j]==NULL) break;
219 this->msg(MSG::INFO) << "FPE stacktrace " << j << " :\n";
220 FPEAudit::resolve(FPEAudit::s_tlsdata.s_array_O[j],this->msg());
222 this->msg(MSG::INFO) << endmsg;
223 }
224 }
225 }
226 if (raised & FE_INVALID) {
227 ATH_MSG_WARNING("FPE INVALID in [" << step << "] of [" << caller << "]" << evStr.str()
229 );
231 }
232 if ( m_NstacktracesOnFPE && FPEAudit::s_tlsdata.s_array_I[0] != NULL )
233 {
234 for (unsigned int j = 0; j < m_Nstacklines; j++)
235 {
237 if (FPEAudit::s_tlsdata.s_array_I[j]==NULL) break;
238 this->msg(MSG::INFO) << "FPE stacktrace " << j << " :\n";
239 FPEAudit::resolve(FPEAudit::s_tlsdata.s_array_I[j],this->msg());
241 this->msg(MSG::INFO) << endmsg;
242 }
243 }
244 if (raised & FE_DIVBYZERO) {
245 ATH_MSG_WARNING("FPE DIVBYZERO in [" << step << "] of [" << caller << "]" << evStr.str()
247 );
249 if ( m_NstacktracesOnFPE && FPEAudit::s_tlsdata.s_array_D[0] != NULL )
250 {
252 for (unsigned int j = 0; j < m_Nstacklines; j++)
253 {
254 if (FPEAudit::s_tlsdata.s_array_D[j]==NULL) break;
255 this->msg(MSG::INFO) << "FPE stacktrace " << j << " :\n";
256 FPEAudit::resolve(FPEAudit::s_tlsdata.s_array_D[j],this->msg());
258 this->msg(MSG::INFO) << endmsg;
259 }
260 }
261 }
262
263
265 if ( --m_nexceptions == 0
268 {
269 fprintf(stderr, "too many SIGFPE detected, will be uninstalling signal handler\n");
271 }
272 }
273}
#define endmsg
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ UninstallHandler()

void FPEAuditor::UninstallHandler ( )
private

Definition at line 147 of file FPEAuditor.cxx.

148{
149 ATH_MSG_INFO("uninstalling SignalHandler");
151
152 feclearexcept(FE_ALL_EXCEPT);
153 fesetenv (&m_env);
154 FPEAudit::mask_fpe();
155
156 // feenableexcept (0);
157 // fedisableexcept (FE_ALL_EXCEPT);
158}

Member Data Documentation

◆ m_CountFPEs

std::atomic<unsigned int> FPEAuditor::m_CountFPEs[FPEAUDITOR_ARRAYSIZE]
private

Definition at line 77 of file FPEAuditor.h.

◆ m_env

fenv_t FPEAuditor::m_env
private

The FP environment before we initialize.

Definition at line 90 of file FPEAuditor.h.

◆ m_nexceptions

std::atomic<int> FPEAuditor::m_nexceptions
private

Definition at line 92 of file FPEAuditor.h.

◆ m_Nstacklines

unsigned int FPEAuditor::m_Nstacklines =100
private

Definition at line 81 of file FPEAuditor.h.

◆ m_NstacktracesOnFPE

unsigned int FPEAuditor::m_NstacktracesOnFPE =0
private

Definition at line 79 of file FPEAuditor.h.


The documentation for this class was generated from the following files: