File: CrashHandling.cpp

package info (click to toggle)
tulip 3.7.0dfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 39,428 kB
  • sloc: cpp: 231,403; php: 11,023; python: 1,128; sh: 671; yacc: 522; makefile: 315; xml: 63; lex: 55
file content (159 lines) | stat: -rwxr-xr-x 4,527 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
 *
 * This file is part of Tulip (www.tulip-software.org)
 *
 * Authors: David Auber and the Tulip development Team
 * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
 *
 * Tulip is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * Tulip is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 */

#include <tulip/SystemDefinition.h>
#include <tulip/TulipRelease.h>

#include <iostream>
#include <cstring>

#include "CrashHandling.h"
#include "StackWalker.h"

using namespace std;

/*
  Linux/MacOS-specific handling
 */
#if defined(__unix__) || defined(__APPLE__)

# if defined(__i386__) || defined(__amd64__)

#include "UnixSignalInterposer.h"

#if defined(__APPLE__)
#include <sys/ucontext.h>
#else

// This structure mirrors the one found in /usr/include/asm/ucontext.h
typedef struct _sig_ucontext {
  unsigned long     uc_flags;
  struct ucontext   *uc_link;
  stack_t           uc_stack;
  struct sigcontext uc_mcontext;
  sigset_t          uc_sigmask;
} sig_ucontext_t;

#endif

void dumpStack(int sig, siginfo_t *, void * ucontext) {

  // Get the address at the time the signal was raised from the EIP (x86) or RIP (x86_64)

#ifndef __APPLE__

  sig_ucontext_t * uc = reinterpret_cast<sig_ucontext_t *>(ucontext);
#ifdef I64
  void *callerAddress = reinterpret_cast<void *>(uc->uc_mcontext.rip); // x86_64 specific;
#else
  void *callerAddress = reinterpret_cast<void *>(uc->uc_mcontext.eip); // x86 specific;
#endif

#else

  ucontext_t * uc = reinterpret_cast<ucontext_t *>(ucontext);
#ifndef I64
  void *callerAddress = reinterpret_cast<void *>(uc->uc_mcontext->__ss.__eip);
#else
  void *callerAddress = reinterpret_cast<void *>(uc->uc_mcontext->__ss.__rip);
#endif

#endif

  std::cerr << TLP_PLATEFORM_HEADER << " " << OS_PLATFORM << std::endl
            << TLP_ARCH_HEADER << " "  << OS_ARCHITECTURE << std::endl
            << TLP_COMPILER_HEADER << " "  << OS_COMPILER  << std::endl
            << TLP_VERSION_HEADER << " " << TULIP_RELEASE  << std::endl;

  std::cerr << "Caught signal " << sig << " (" << strsignal(sig) << ")" << std::endl;

  std::cerr << TLP_STACK_BEGIN_HEADER << std::endl;
  StackWalkerGCC sw;
  sw.setCallerAddress(callerAddress);
  sw.printCallStackToStdErr();
  std::cerr << TLP_STACK_END_HEADER << std::endl;
  std::cerr << std::flush;
  installSignalHandler(sig, SIG_DFL);
}

extern void installSignalHandlers(void);

void start_crash_handler() {
  installSignalHandler(SIGSEGV, &dumpStack);
  installSignalHandler(SIGABRT, &dumpStack);
  installSignalHandler(SIGFPE, &dumpStack);
  installSignalHandler(SIGILL, &dumpStack);
  installSignalHandler(SIGBUS, &dumpStack);
}

# else
// architecture not supported
void start_crash_handler() {}
# endif

/*
  MinGW-specific handling
 */
#elif defined(__MINGW32__)

static LONG WINAPI
exception_filter(LPEXCEPTION_POINTERS info) {
  StackWalkerMinGW sw;
  sw.setContext(info->ContextRecord);

  std::cerr << TLP_PLATEFORM_HEADER << " " << OS_PLATFORM << std::endl
            << TLP_ARCH_HEADER << " "  << OS_ARCHITECTURE << std::endl
            << TLP_COMPILER_HEADER << " "  << OS_COMPILER  << std::endl
            << TLP_VERSION_HEADER << " " << TULIP_RELEASE  << std::endl;
  std::cerr << TLP_STACK_BEGIN_HEADER << std::endl;
  sw.printCallStackToStdErr();
  std::cerr << TLP_STACK_END_HEADER << std::endl;
  std::cerr << std::flush;

  return 1;
}


void start_crash_handler() {
  SetUnhandledExceptionFilter(exception_filter);
}

#elif defined(_MSC_VER)

static LONG WINAPI
exception_filter(LPEXCEPTION_POINTERS info) {
  StackWalkerMSVC sw;
  sw.setContext(info->ContextRecord);

  std::cerr << TLP_PLATEFORM_HEADER << " " << OS_PLATFORM << std::endl
            << TLP_ARCH_HEADER << " "  << OS_ARCHITECTURE << std::endl
            << TLP_COMPILER_HEADER << " "  << OS_COMPILER  << std::endl
            << TLP_VERSION_HEADER << " " << TULIP_RELEASE  << std::endl;
  std::cerr << TLP_STACK_BEGIN_HEADER << std::endl;
  sw.printCallStackToStdErr();
  std::cerr << TLP_STACK_END_HEADER << std::endl;
  std::cerr << std::flush;
  return 1;
}


void start_crash_handler() {
  SetUnhandledExceptionFilter(exception_filter);
}
#endif