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  gdb_backtrace();
46 
47  // gdb_backtrace() never returns. But if it did, this would be the right
48  // way to exit with the correct code.
49  _exit(sig+128);
50  }
51 
53  {
54  public:
56  {
57  // We're already being debugged somehow. Don't complicate things
58  if(getenv("CAFE_NO_BACKTRACE")) return;
59 
60  // Check that this is really a CAFAna job. Somehow this library gets
61  // loaded into art jobs too??
62  char s[1024];
63  sprintf(s, "/proc/%d/cmdline", getpid());
64  std::ifstream f(s);
65  if(f){
67  f >> ss;
68  if(ss.find("root.exe") == std::string::npos) return;
69  }
70 
71  // Handle uncaught exceptions
72  std::set_terminate(handle_terminate);
73 
74  // Handle abort(), segfaults, bus errors, and FPEs
75  struct sigaction sa;
76  memset(&sa, 0, sizeof(sa));
77  sigemptyset(&sa.sa_mask);
78 
79  sa.sa_sigaction = handle_signal;
80  sa.sa_flags = SA_SIGINFO;
81 
82  sigaction(SIGABRT, &sa, NULL);
83  sigaction(SIGSEGV, &sa, NULL);
84  sigaction(SIGBUS, &sa, NULL);
85  sigaction(SIGFPE, &sa, NULL);
86  }
87  };
88 
90 }
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
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void gdb_backtrace()
void handle_signal(int sig, siginfo_t *, void *)
static InstallHandlers gHandlerInstaller