~ubuntu-branches/debian/jessie/armory/jessie

« back to all changes in this revision

Viewing changes to cppForSwig/sighandler.cpp

  • Committer: Package Import Robot
  • Author(s): Joseph Bisch
  • Date: 2014-10-07 10:22:45 UTC
  • Revision ID: package-import@ubuntu.com-20141007102245-2s3x3rhjxg689hek
Tags: upstream-0.92.3
ImportĀ upstreamĀ versionĀ 0.92.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef __linux__
 
2
 
 
3
#include "log.h"
 
4
 
 
5
#include <signal.h>
 
6
#include <execinfo.h>
 
7
#include <unistd.h>
 
8
#include <stdio.h>
 
9
#include <sys/types.h>
 
10
#include <sys/stat.h>
 
11
#include <fcntl.h>
 
12
 
 
13
       
 
14
static void sigsegv(int, siginfo_t *info, void*)
 
15
{
 
16
   const int stderr=2;
 
17
   {
 
18
      const char e1[] =
 
19
         "\nArmory has crashed. Please provide the following "
 
20
         "in your bug report:\n"
 
21
         "Failed to dereference address ";
 
22
      ::write(stderr, e1, sizeof(e1)-1);
 
23
   }
 
24
   
 
25
   {
 
26
      char addr[64];
 
27
      int num = snprintf(addr, sizeof(addr), "%p", info->si_addr);
 
28
      ::write(stderr, addr, num);
 
29
      ::write(stderr, "\n", 1);
 
30
   }
 
31
 
 
32
   void* bt_buffer[64];
 
33
   int n = backtrace(bt_buffer, sizeof(bt_buffer)/sizeof(bt_buffer[0]));
 
34
   
 
35
   backtrace_symbols_fd(bt_buffer, n, stderr);
 
36
   
 
37
   // allow crash again, so that the user sees the pretty "Segmentation fault"
 
38
   signal(SIGSEGV, 0);
 
39
   
 
40
   // now try to write that same error to the log file
 
41
   // since Log::filename accesses what might be corrupt memory,
 
42
   // we have to repeat some of the stuff above. So it can crash
 
43
   // here and we still get a log on stderr
 
44
   int log = open(Log::filename().c_str(), O_APPEND, O_WRONLY);
 
45
   if (log != -1)
 
46
   {
 
47
      {
 
48
         const char e1[] =
 
49
            "\n\nSIGSEGV\n"
 
50
            "Failed to dereference address ";
 
51
         ::write(log, e1, sizeof(e1)-1);
 
52
      }
 
53
      {
 
54
         char addr[64];
 
55
         int num = snprintf(addr, sizeof(addr), "%p", info->si_addr);
 
56
         ::write(log, addr, num);
 
57
         ::write(log, "\n", 1);
 
58
      }
 
59
      backtrace_symbols_fd(bt_buffer, n, log);
 
60
      ::close(log);
 
61
   }
 
62
      
 
63
   // now actually crash again so the user sees the error
 
64
   
 
65
   int *crash = (int*)0;
 
66
   *crash = 0;
 
67
}
 
68
 
 
69
static void installSignalHandler()
 
70
{
 
71
   static bool installed=false;
 
72
   if (installed)
 
73
      return;
 
74
   installed = true;
 
75
   
 
76
   struct sigaction action;
 
77
   action.sa_sigaction = sigsegv;
 
78
   action.sa_flags = SA_SIGINFO | SA_NODEFER;
 
79
   
 
80
   sigaction(SIGSEGV, &action, 0);
 
81
}
 
82
 
 
83
namespace
 
84
{
 
85
class Init
 
86
{
 
87
public:
 
88
   Init()
 
89
   {
 
90
      installSignalHandler();
 
91
   }
 
92
};
 
93
}
 
94
 
 
95
static Init install;
 
96
 
 
97
// kate: indent-width 3; replace-tabs on;
 
98
#endif