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 #if defined(USE_BACKTRACE)
46 # if !defined(_INC_BACKTRACE_FUNC)
47 # define _INC_BACKTRACE_FUNC
48 # if !defined(BACKTRACE_SKIP)
49 # define BACKTRACE_SKIP 1
50 # endif
51
52 # include <signal.h>
53
54 static struct backtrace_state *state = NULL;
55 static volatile long bt_pid;
56 static int stopbt, function_count, hidden_function_count,
57 unknown_function_count, backtrace_reported = 0;
58
59 _Noreturn static 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 static 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 static 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 # if defined(SIGUSR2)
125 if (number != SIGUSR2)
126 {
127 (void)fprintf(stderr,
128 "\r\n****** BUG REPORTING **************************************\r\n\r\n");
129 (void)fprintf(stderr,
130 " URL: https://gitlab.com/dps8m/dps8m/-/wikis/Bug-Reporting");
131 }
132 else
133 {
134 (void)fprintf(stderr,
135 "\r\n****** SIGUSR2 RAISED *************************************\r\n\r\n");
136 (void)fprintf(stderr,
137 " SIGUSR2 manually raised or available memory exhausted.");
138 }
139 # endif
140 (void)fprintf(stderr,
141 "\r\n\r\n****** FATAL ERROR ****************************************\r\n");
142 if (bt_pid > 1)
143 {
144 # if defined(SIGUSR2)
145 if (number == SIGUSR2)
146 {
147 (void)fprintf(stderr,
148 "\r\n PID %ld raised SIGUSR2 (signal %d) ... :(\r\n\r\n",
149 (long)bt_pid, number);
150 }
151 else
152 {
153 # endif
154 (void)fprintf(stderr,
155 "\r\n PID %ld caught fatal signal %d ... :(\r\n\r\n",
156 (long)bt_pid, number);
157 # if defined(SIGUSR2)
158 }
159 # endif
160 }
161 else
162 {
163 (void)fprintf(stderr,
164 "\r\n Caught fatal signal %d ... :(\r\n\r\n",
165 number);
166 }
167 backtrace_full(state, BACKTRACE_SKIP, full_callback, error_callback, NULL);
168 if (backtrace_reported)
169 {
170 (void)fprintf(stderr,
171 "\r (%d earlier caller%s not shown)\r\n",
172 hidden_function_count, hidden_function_count > 1 ? "s" : "");
173 }
174 (void)fprintf(stderr,
175 "\r\n***********************************************************\r\n\r\n");
176 # if defined(USE_DUMA)
177 DUMA_CHECKALL();
178 # endif
179 abort();
180 }
181 # endif
182 #endif