FPCTest_module.cc
Go to the documentation of this file.
1 // vim: set sw=2 expandtab :
2 
6 #include "fpc_utils.h"
8 
9 #include <cmath>
10 #include <csignal>
11 #include <cstdlib>
12 #include <iostream>
13 #include <stdexcept>
14 
15 #include <float.h>
16 
17 using namespace std;
18 using namespace art;
19 
20 extern "C" {
21 void
22 handle_sigfpe(int, siginfo_t*, void*)
23 {
24  cerr << "Worked!\n";
25  exit(0);
26 }
27 } // extern "C"
28 
29 namespace arttest {
30 
31  class FPCTest : public EDAnalyzer {
32  public:
33  explicit FPCTest(fhicl::ParameterSet const&);
34 
35  private:
36  void analyze(Event const&);
37  };
38 
39  FPCTest::FPCTest(fhicl::ParameterSet const& p) : EDAnalyzer{p}
40  {
41  // Install the SIGFPE handler.
42  struct sigaction act;
43  memset(&act, 0, sizeof(act));
44  act.sa_sigaction = handle_sigfpe;
45  act.sa_flags = SA_RESTART;
46  if (sigaction(SIGFPE, &act, 0) != 0) {
47  perror("sigaction failed");
48  throw runtime_error("cannot install sigaction signal handler");
49  }
50  // Block the floating point exception signal SIGFPE.
51  // We need this to be done in the main thread early
52  // so that it is blocked in all threads started by tbb.
53  sigset_t newset;
54  sigemptyset(&newset);
55  sigaddset(&newset, SIGFPE);
56  pthread_sigmask(SIG_BLOCK, &newset, 0);
57  }
58 
59  void
61  {
62  double const x{1.0};
63  double const y{DBL_MAX};
64  if (e.id().event() == 2) {
65  // Allow the floating point exception signal SIGFPE.
66  sigset_t newset;
67  sigemptyset(&newset);
68  sigaddset(&newset, SIGFPE);
69  pthread_sigmask(SIG_UNBLOCK, &newset, 0);
70  // Show the variable values.
71  mf::LogVerbatim("FPExceptions") << "\n\t\tx = " << x;
72  mf::LogVerbatim("FPExceptions") << "\t\ty = " << y << " (DBL_MAX)";
73  // DivideByZero
74  mf::LogVerbatim("FPExceptions") << "\t\tForce DivideByZero: a = x/zero";
75  double const a{divit(x, 0)};
76  mf::LogVerbatim("FPExceptions") << "\t\ta = " << a;
77  // Invalid
78  mf::LogVerbatim("FPExceptions") << "\t\tForce Invalid: b = log(-1.0)";
79  double const b{log(-1.0)};
80  mf::LogVerbatim("FPExceptions") << "\t\tb = " << b;
81  // Overflow (actually precision)
82  mf::LogVerbatim("FPExceptions") << "\t\tForce Overflow: c = y*y";
83  double const c{multit(y, y)};
84  mf::LogVerbatim("FPExceptions") << "\t\tc = " << c;
85  // Underflow (actually precision)
86  mf::LogVerbatim("FPExceptions") << "\t\tForce Underflow: d = x/y";
87  double const d{divit(x, y)};
88  mf::LogVerbatim("FPExceptions") << "\t\td = " << d;
89  abort();
90  }
91  }
92 } // namespace arttest
93 
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:69
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
STL namespace.
void analyze(Event const &)
double multit(double x, double y)
Definition: fpc_utils.cc:11
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
const double a
p
Definition: test.py:223
static bool * b
Definition: config.cpp:1043
void handle_sigfpe(int, siginfo_t *, void *)
EventNumber_t event() const
Definition: EventID.h:116
list x
Definition: train.py:276
EventID id() const
Definition: Event.cc:34
double divit(double x, double y)
Definition: fpc_utils.cc:4