Scarab  v2.2.0
Project 8 C++ Utility Library
terminate.cc
Go to the documentation of this file.
1 /*
2  * terminate.cc
3  *
4  * Created on: May 23, 2017
5  * Author: N.S. Oblath
6  */
7 
8 #include "terminate.hh"
9 
10 #include "logger.hh"
11 
12 //#include <boost/core/demangle.hpp>
13 
14 #include <execinfo.h>
15 //#include <signal.h>
16 #include <string.h>
17 
18 //#include <cstdlib>
19 #include <mutex>
20 #include <stdexcept>
21 
22 namespace {
23  // invoke set_terminate as part of global constant initialization
24  static const bool SET_TERMINATE = std::set_terminate( scarab::terminate );
25 }
26 
27 LOGGER( slog, "terminate" );
28 
29 namespace scarab
30 {
31  // Option 1: Use the terminate() function
32  void terminate()
33  {
34  static std::mutex t_using_terminate;
35  std::unique_lock< std::mutex > t_terminate_locked( t_using_terminate );
36 
37  static bool t_tried_throw = false;
38 
39  try
40  {
41  // try once to re-throw currently active exception
42  if( ! t_tried_throw )
43  {
44  t_tried_throw = true;
45  throw;
46  }
47  }
48  catch( const std::exception &e )
49  {
50  LERROR( slog, "Caught unhandled exception. what(): " << e.what() );
51  }
52  catch (...)
53  {
54  LERROR( slog, "Caught unknown (non-std::exception) & unhandled exception." );
55  }
56 
57  void* t_bt_array[50];
58  int size = backtrace( t_bt_array, 50 );
59 
60  LERROR( slog, "Backtrace from terminate() returned "
61  << size << " frames\n" );
62 
63  char** t_messages = backtrace_symbols( t_bt_array, size );
64 
65  std::stringstream t_bt_str;
66  for( int i = 0; i < size && t_messages != nullptr; ++i )
67  {
68  t_bt_str << "[bt]: (" << i << ") " << t_messages[i] << '\n';
69  }
70  LERROR( slog, "Backtrace:\n" << t_bt_str.str() );
71 
72  free( t_messages );
73 
74  abort();
75  }
76 
77  // Option 2: Handle SIGABRT
78 /*
79  void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
80  {
81  LERROR( slog, "signal " << sig_num
82  << " (" << strsignal(sig_num) << "), address is "
83  << info->si_addr );//<< " from "
84  //<< caller_address );
85 
86  void* array[50];
87  int size = backtrace(array, 50);
88 
89  LERROR(slog, "Backtrace from signal handler returned " << size << " frames\n" );
90 
91  char** messages = backtrace_symbols(array, size);
92 
93  // skip first stack frame (points here)
94  std::stringstream bt_str;
95  for( int i = 1; i < size && messages != NULL; ++i )
96  {
97  bt_str << "[bt]: (" << i << ") " << messages[i] << '\n';
98  }
99  LERROR( slog, "Backtrace:\n" << bt_str.str() );
100 
101  free(messages);
102 
103  exit(EXIT_FAILURE);
104  }
105 */
106 
107 } /* namespace scarab */
#define LERROR(...)
Definition: logger.hh:365
LOGGER(slog,"terminate")
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
void terminate()
Definition: terminate.cc:32