Synopsis - Cross-Reference

File: /src/Support/ErrorHandler.cc
 1//
 2// Copyright (C) 2004 Stefan Seefeld
 3// All rights reserved.
 4// Licensed to the public under the terms of the GNU LGPL (>= 2),
 5// see the file COPYING for details.
 6//
 7
 8#include "ErrorHandler.hh"
 9#include <iostream>
10#include <cstdlib>
11
12#ifndef _WIN32
13# include <signal.h>
14# include <sys/wait.h>
15# ifdef __GLIBC__
16#  include <execinfo.h>
17# endif
18#endif
19
20namespace
21{
22Synopsis::ErrorHandler::Callback callback = 0;
23
24#ifndef _WIN32
25  struct sigaction olda;
26  struct sigaction newa;
27#endif
28  
29void print_stack()
30{
31#ifdef __GLIBC__
32  void *bt[128];
33  int bt_size = backtrace(bt, sizeof(bt) / sizeof(void *));
34  char **symbols = backtrace_symbols (bt, bt_size);
35  for (int i = 0; i < bt_size; i++) std::cout << symbols[i] << std::endl;
36#endif
37}
38
39void sighandler(int signo)
40{
41  std::string signame = "Signal";
42
43#ifndef _WIN32
44  switch (signo)
45  {
46    case SIGABRT:
47        signame = "Abort";
48        break;
49    case SIGBUS:
50        signame = "Bus error";
51        break;
52    case SIGSEGV:
53        signame = "Segmentation Violation";
54        break;
55    default:
56        signame = "unknown";
57        break;
58  };
59#endif
60
61  std::cerr << signame << " caught" << std::endl;
62  if (callback) callback();
63  print_stack();
64  exit(-1);
65}
66
67}
68
69using namespace Synopsis;
70
71ErrorHandler::ErrorHandler(Callback c)
72{
73  callback = c;
74#ifndef _WIN32
75  newa.sa_handler = &sighandler;
76  sigaction(SIGSEGV, &newa, &olda);
77  sigaction(SIGBUS, &newa, &olda);
78  sigaction(SIGABRT, &newa, &olda);
79#endif  
80}
81
82ErrorHandler::~ErrorHandler()
83{
84#ifndef _WIN32
85  sigaction(SIGABRT, &olda, 0);
86  sigaction(SIGBUS, &olda, 0);
87  sigaction(SIGSEGV, &olda, 0);
88#endif
89}
90