Belle II Software  release-08-01-10
TheKillerModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <framework/modules/core/TheKillerModule.h>
10 #include <csignal>
11 #include <boost/algorithm/string.hpp>
12 
13 using namespace Belle2;
14 
15 //-----------------------------------------------------------------
16 // Register the Module
17 //-----------------------------------------------------------------
18 REG_MODULE(TheKiller);
19 
20 //-----------------------------------------------------------------
21 // Implementation
22 //-----------------------------------------------------------------
23 
25 {
26  // Set module properties
27  setDescription(R"DOC(This Modules kills basf2 as horribly as possible (or as selected)
28 
29 With this module you can kill basf2 in a variety of ways to test what happens if processing is interrupted by
30 
31 * std::abort()
32 * std::terminate()
33 * std::quick_exit()
34 * std::exit(N)
35 * uncaught exception
36 * signal
37 * segfault
38 * bus error
39 
40 This error can occur in a selected event to test behavior during processing.)DOC");
41 
42  // Parameter definitions
43  addParam("method", m_methodStr, "How to kill the event, one of (abort, terminate, "
44  "quick_exit, exit, exception, signal, segfault, buserror)", std::string("abort"));
45  addParam("parameter", m_parameter, "Optional parameter for the kill method: for "
46  "quick_exit and exit it is the return code, for signal it is the signal number", 0u);
47  addParam("event", m_eventToKill, "In which event to kill the processing");
48 }
49 
51 {
52  boost::to_lower(m_methodStr);
53  if (m_methodStr == "abort") m_method = EMethod::c_abort;
54  else if (m_methodStr == "terminate") m_method = EMethod::c_terminate;
55  else if (m_methodStr == "quick_exit") m_method = EMethod::c_quick_exit;
56  else if (m_methodStr == "exit") m_method = EMethod::c_exit;
57  else if (m_methodStr == "exception") m_method = EMethod::c_exception;
58  else if (m_methodStr == "signal") m_method = EMethod::c_signal;
59  else if (m_methodStr == "segfault") m_method = EMethod::c_segfault;
60  else if (m_methodStr == "buserror") m_method = EMethod::c_buserror;
61  else B2ERROR("Unknown method , choose one of (abort, terminate, quick_exit, exit, "
62  "exception, signal, segfault)" << LogVar("method", m_methodStr));
63 }
64 
66 {
67  if (++m_event < m_eventToKill) return;
68  switch (m_method) {
69  case EMethod::c_abort:
70  std::abort();
72  std::terminate();
74  std::quick_exit(m_parameter);
75  case EMethod::c_exit:
76  std::exit(m_parameter);
78  throw std::runtime_error("This is a runtime error kindly provided by TheKiller module.");
79  case EMethod::c_signal:
80  if (raise(m_parameter) != 0) B2FATAL("Invalid signal number" << LogVar("signal", m_parameter));
81  break;
83 #ifndef __clang_analyzer__
84  {
85  // this is an intentional nullptr dereference so lets hide it from clang analyzer
86  volatile int* foo {nullptr};
87  *foo = 5;
88  }
89 #endif
90  break;
92 #ifndef __clang_analyzer__
93  {
94 #if defined(__GNUC__) && defined(__x86_64__)
95  __asm__("pushf\norl $0x40000,(%rsp)\npopf");
96 #endif
97  auto* cptr = (char*) malloc(sizeof(int) + 1);
98  auto* iptr = (int*)(cptr + 1);
99  *iptr = 42;
100  free(cptr);
101  }
102 #endif
103  break;
104  default:
105  B2FATAL("Illegal method");
106  }
107  B2FATAL("This should never be called ...");
108 }
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
EMethod m_method
How to kill the event after parsing the string parameter.
void initialize() override
parse the method parameter
void event() override
kill if necessary
std::string m_methodStr
How to kill the event, one of (abort, terminate, quick_exit, exit, exception, signal,...
int m_event
Current event.
@ c_exception
raise std::runtime_error
@ c_terminate
call std::terminate
@ c_quick_exit
call std::quick_exit
int m_eventToKill
In which event to kill the processing.
TheKillerModule()
Constructor: Sets the description, the properties and the parameters of the module.
unsigned int m_parameter
Optional parameter for the kill method: for quick_exit and exit it is the return code,...
Class to store variables with their name which were sent to the logging service.
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
Abstract base class for different kinds of events.