1 /* -*- linux-c -*- */
2
3 /* Taken from
4 * http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
5 * and tailored to Aqualung.
6 */
7
8 /* $Id: segv.c 1245 2012-02-04 10:33:30Z assworth $ */
9
10 #include <config.h>
11
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <signal.h>
17
18 #ifdef DEBUG_BUILD
19
20 #include <execinfo.h>
21
22 #include "version.h"
23
24 #endif /* DEBUG_BUILD */
25
26 #include "segv.h"
27
28
29 #ifdef DEBUG_BUILD
30 static void
signal_segv(int signum,siginfo_t * info,void * ptr)31 signal_segv(int signum, siginfo_t * info, void * ptr) {
32
33 unsigned i;
34 void *bt[20];
35 char **strings;
36 size_t sz;
37
38 fprintf(stderr, "===[ Aqualung %s CRASH REPORT ]===\n", AQUALUNG_VERSION);
39 #ifdef HAVE_PSIGINFO
40 psiginfo(info, "Caught");
41 #else
42 psignal(signum, "Caught");
43 #endif
44 fprintf(stderr, "Please mail this to <aqualung-friends@lists.sourceforge.net>\n");
45 fprintf(stderr, "along with a short description of what you were doing when\n");
46 fprintf(stderr, "the program crashed. Please also send the output of `aqualung -v'.\n");
47 fprintf(stderr, "Thank you in advance!\n");
48
49 sz = backtrace(bt, 20);
50 strings = backtrace_symbols(bt, sz);
51
52 fprintf(stderr, "\nbacktrace (%zd stack frames)\n", sz);
53 for(i = 0; i < sz; ++i)
54 fprintf(stderr, "%s\n", strings[i]);
55 fprintf(stderr, "===[ END OF CRASH REPORT ]===\n");
56
57 free(strings);
58 exit (-1);
59 }
60 #endif /* DEBUG_BUILD */
61
62 #ifdef RELEASE_BUILD
63 static void
signal_segv(int signum,siginfo_t * info,void * ptr)64 signal_segv(int signum, siginfo_t * info, void * ptr) {
65
66 fprintf(stderr, "Aqualung received signal %d (%s).\n\n",
67 signum, strsignal(signum));
68 #ifndef _WIN32
69 fprintf(stderr, "To help the developers fix the bug causing this crash,\n");
70 fprintf(stderr, "please do the following:\n\n");
71 fprintf(stderr, "1) configure & make Aqualung with --enable-debug\n");
72 fprintf(stderr, "2) reproduce the crash\n");
73 fprintf(stderr, "3) send the crash report to the developers\n\n");
74 fprintf(stderr, "Thank you for supporting Aqualung!\n");
75 #endif /* !_WIN32 */
76 exit(-1);
77 }
78 #endif /* RELEASE_BUILD */
79
80 int
setup_sigsegv()81 setup_sigsegv() {
82 struct sigaction action;
83 memset(&action, 0, sizeof(action));
84 action.sa_sigaction = signal_segv;
85 action.sa_flags = SA_SIGINFO;
86
87 if (sigaction(SIGFPE, &action, NULL) < 0) {
88 perror("sigaction");
89 return 0;
90 }
91 if (sigaction(SIGILL, &action, NULL) < 0) {
92 perror("sigaction");
93 return 0;
94 }
95 if (sigaction(SIGSEGV, &action, NULL) < 0) {
96 perror("sigaction");
97 return 0;
98 }
99 if (sigaction(SIGBUS, &action, NULL) < 0) {
100 perror("sigaction");
101 return 0;
102 }
103 if (sigaction(SIGABRT, &action, NULL) < 0) {
104 perror("sigaction");
105 return 0;
106 }
107 return 1;
108 }
109
110 #ifndef SIGSEGV_NO_AUTO_INIT
111 static void
112 __attribute((constructor))
init(void)113 init(void) {
114 setup_sigsegv();
115 }
116 #endif
117
118 // vim: shiftwidth=8:tabstop=8:softtabstop=8 :
119
120