This source file includes following definitions.
- error_callback
- full_callback
- backtrace_handler
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 #ifdef USE_BACKTRACE
46 # ifndef _INC_BACKTRACE_FUNC
47 # define _INC_BACKTRACE_FUNC
48 # ifndef BACKTRACE_SKIP
49 # define BACKTRACE_SKIP 1
50 # endif
51
52 # include <signal.h>
53
54 struct backtrace_state *state = NULL;
55 volatile long bt_pid;
56 int stopbt, function_count, hidden_function_count,
57 unknown_function_count, backtrace_reported = 0;
58
59 _Noreturn void
60 error_callback(void *data, const char *message, int error_number)
61 {
62 sigset_t block; sigset_t block_n;
63 sigfillset(&block); sigfillset(&block_n);
64 sigprocmask(SIG_SETMASK, &block, &block_n);
65 (void)data; (void)error_number;
66 (void)fprintf(stderr, "\r No backtrace: %s\r\n", message);
67 (void)fprintf(stderr,
68 "\r\n****************************************************\r\n\r\n");
69 abort();
70 }
71
72 int
73 full_callback(void *data, uintptr_t pc, const char *pathname,
74 int line_number, const char *function)
75 {
76 (void)data; (void)pc;
77 function_count++;
78 if (pathname != NULL || function != NULL || line_number != 0)
79 {
80 if (!stopbt)
81 {
82 (void)fprintf(stderr, "\r %-.3d: %s()\r\n %s:%d\r\n",
83 function_count, function, pathname, line_number);
84 backtrace_reported++;
85 int n = strcmp(function, BACKTRACE_MAIN);
86 if (n == 0)
87 {
88 stopbt = 1;
89 }
90 }
91 else
92 {
93 return 0;
94 }
95 }
96 else
97 {
98 if (function_count > 1)
99 {
100 if (!stopbt)
101 {
102 (void)fprintf(stderr, "\r %-.3d: ???\r\n", function_count);
103 }
104 else
105 {
106 hidden_function_count++;
107 }
108 unknown_function_count++;
109 }
110 else
111 {
112 function_count--;
113 }
114 }
115 return 0;
116 }
117
118 _Noreturn void
119 backtrace_handler(int number)
120 {
121 sigset_t block; sigset_t block_n;
122 sigfillset(&block); sigfillset(&block_n);
123 sigprocmask(SIG_SETMASK, &block, &block_n);
124 (void)fprintf(
125 stderr, "\r\n\r\n****** FATAL ERROR *********************************\r\n");
126 if (bt_pid > 1)
127 {
128 # ifdef SIGUSR2
129 if (number == SIGUSR2)
130 {
131 (void)fprintf(stderr,
132 "\r\n PID %ld raised SIGUSR2 (signal %d) ... :(\r\n\r\n",
133 (long)bt_pid, number);
134 }
135 else
136 {
137 # endif
138 (void)fprintf(stderr,
139 "\r\n PID %ld caught fatal signal %d ... :(\r\n\r\n",
140 (long)bt_pid, number);
141 # ifdef SIGUSR2
142 }
143 # endif
144 }
145 else
146 {
147 (void)fprintf(stderr,
148 "\r\n Caught fatal signal %d ... :(\r\n\r\n",
149 number);
150 }
151 backtrace_full(state, BACKTRACE_SKIP, full_callback, error_callback, NULL);
152 if (backtrace_reported)
153 {
154 if (hidden_function_count > 1)
155 {
156 (void)fprintf(stderr,
157 "\r (%d earlier callers not shown)\r\n",
158 hidden_function_count);
159 }
160 if (hidden_function_count == 1)
161 {
162 (void)fprintf(stderr,
163 "\r (%d earlier caller not shown)\r\n",
164 hidden_function_count);
165 }
166 }
167 # ifdef SIGUSR2
168 if (number != SIGUSR2)
169 {
170 (void)fprintf(stderr,
171 "\r\n****** BUG REPORTING *******************************\r\n\r\n");
172 (void)fprintf(stderr,
173 " URL: https://dps8m.gitlab.io/dps8m/Bug_Reporting/\r\n");
174 }
175 # endif
176 (void)fprintf(stderr,
177 "\r\n****************************************************\r\n\r\n");
178 # ifdef USE_DUMA
179 DUMA_CHECKALL();
180 # endif
181 abort();
182 }
183 # endif
184 #endif