DebugHelpers.cxx
Go to the documentation of this file.
1 // This file sets things up (when libCAFAnaCore is loaded) so that we invoke
2 // gdb to get a stack trace after any unusual program termination. You can
3 // suppress this behaviour by setting the CAFE_NO_BACKTRACE environment
4 // variable.
5 
6 #include <csignal>
7 #include <cstring>
8 #include <fstream>
9 
10 #include <unistd.h>
11 
12 #include <iostream>
13 
14 namespace ana
15 {
17  {
18  // Have to end with a 'kill' command, otherwise GDB winds up sending us
19  // SIGSTOP and never resuming us afterwards.
20  char s[1024];
21  sprintf(s, "gdb --batch -ex 'set confirm off' -ex sharedlibrary -ex bt -ex kill root.exe %d", getpid());
22  system(s);
23  }
24 
25  bool gIsException = false;
26 
28  {
29  std::cout << "\n\nUncaught exception\n" << std::endl;
30  gIsException = true;
31  // Next thing that happens is abort(), which goes to handle_signal()
32  }
33 
34  void handle_signal(int sig, siginfo_t*, void*)
35  {
36  if(sig == SIGABRT && !gIsException)
37  std::cout << "\n\nAborted\n" << std::endl;
38  if(sig == SIGSEGV)
39  std::cout << "\n\nSegmentation fault\n" << std::endl;
40  if(sig == SIGFPE)
41  std::cout << "\n\nFloating point exception\n" << std::endl;
42  if(sig == SIGBUS)
43  std::cout << "\n\nBus error\n" << std::endl;
44 
45  std::cout << "Starting backtrace using gdb..." << std::endl;
46  std::cout << "You can use 'export CAFE_NO_BACKTRACE=1' to skip backtraces in future if desired" << std::endl;
47 
48  gdb_backtrace();
49 
50  // gdb_backtrace() never returns. But if it did, this would be the right
51  // way to exit with the correct code.
52  _exit(sig+128);
53  }
54 
56  {
57  public:
59  {
60  // We're already being debugged somehow. Don't complicate things
61  if(getenv("CAFE_NO_BACKTRACE")) return;
62 
63  // Check that this is really a CAFAna job. Somehow this library gets
64  // loaded into art jobs too??
65  char s[1024];
66  sprintf(s, "/proc/%d/cmdline", getpid());
67  std::ifstream f(s);
68  if(f){
70  f >> ss;
71  if(ss.find("root.exe") == std::string::npos) return;
72  }
73 
74  // Handle uncaught exceptions
75  std::set_terminate(handle_terminate);
76 
77  // Handle abort(), segfaults, bus errors, and FPEs
78  struct sigaction sa;
79  memset(&sa, 0, sizeof(sa));
80  sigemptyset(&sa.sa_mask);
81 
82  sa.sa_sigaction = handle_signal;
83  sa.sa_flags = SA_SIGINFO;
84 
85  sigaction(SIGABRT, &sa, NULL);
86  sigaction(SIGSEGV, &sa, NULL);
87  sigaction(SIGBUS, &sa, NULL);
88  sigaction(SIGFPE, &sa, NULL);
89  }
90  };
91 
93 }
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
system("rm -rf microbeam.root")
Float_t ss
Definition: plot.C:24
bool gIsException
const XML_Char * s
Definition: expat.h:262
std::string getenv(std::string const &name)
void handle_terminate()
OStream cout
Definition: OStream.cxx:6
void gdb_backtrace()
void handle_signal(int sig, siginfo_t *, void *)
static InstallHandlers gHandlerInstaller
enum BeamMode string