36
36
37
37
extern " C" {
38
38
39
- // These will be pointers to PROGMEM const strings
40
- static const char * s_panic_file = 0 ;
41
- static int s_panic_line = 0 ;
42
- static const char * s_panic_func = 0 ;
43
- static const char * s_panic_what = 0 ;
44
-
45
- // Our wiring for abort() and C++ exceptions
46
- static bool s_abort_called = false ;
47
- static const char * s_unhandled_exception = NULL ;
48
-
49
- // Common way to notify about where the stack smashing happened
50
- // (but, **only** if caller uses our handler function)
51
- static uint32_t s_stacksmash_addr = 0 ;
52
-
53
- void abort () __attribute__((noreturn));
54
- static void uart_write_char_d (char c);
55
- static void uart0_write_char_d (char c);
56
- static void uart1_write_char_d (char c);
57
- static void print_stack (uint32_t start, uint32_t end);
58
-
59
39
// using numbers different from "REASON_" in user_interface.h (=0..6)
60
40
enum rst_reason_sw
61
41
{
62
42
REASON_USER_STACK_SMASH = 253 ,
63
43
REASON_USER_SWEXCEPTION_RST = 254
64
44
};
65
- static int s_user_reset_reason = REASON_DEFAULT_RST;
45
+
46
+ static struct PostmortemInfo {
47
+ int user_reset_reason; // REASON_DEFAULT_RST;
48
+
49
+ // These will be pointers to PROGMEM const strings
50
+ const char * panic_file; // 0;
51
+ int panic_line; // 0;
52
+ const char * panic_func; // 0;
53
+ const char * panic_what; // 0;
54
+
55
+ // Our wiring for abort() and C++ exceptions
56
+ bool abort_called; // false;
57
+ const char * unhandled_exception; // NULL;
58
+
59
+ // Common way to notify about where the stack smashing happened
60
+ // (but, **only** if caller uses our handler function)
61
+ uint32_t stacksmash_addr; // 0;
62
+ } s_pm = {REASON_DEFAULT_RST, 0 , 0 , 0 , 0 , false , NULL , 0 };
66
63
67
64
// From UMM, the last caller of a malloc/realloc/calloc which failed:
68
- extern void *umm_last_fail_alloc_addr;
69
- extern int umm_last_fail_alloc_size;
65
+ extern struct umm_last_fail_alloc {
66
+ const void *addr;
67
+ size_t size;
70
68
#if defined(DEBUG_ESP_OOM)
71
- extern const char *umm_last_fail_alloc_file ;
72
- extern int umm_last_fail_alloc_line ;
69
+ const char *file ;
70
+ int line ;
73
71
#endif
72
+ } _umm_last_fail_alloc;
73
+
74
+
75
+ void abort () __attribute__((noreturn));
76
+ static void uart_write_char_d (char c);
77
+ static void uart0_write_char_d (char c);
78
+ static void uart1_write_char_d (char c);
79
+ static void print_stack (uint32_t start, uint32_t end);
74
80
75
81
static void raise_exception () __attribute__((noreturn));
76
82
@@ -116,7 +122,7 @@ void __wrap_system_restart_local() {
116
122
117
123
struct rst_info rst_info;
118
124
memset (&rst_info, 0 , sizeof (rst_info));
119
- if (s_user_reset_reason == REASON_DEFAULT_RST)
125
+ if (s_pm. user_reset_reason == REASON_DEFAULT_RST)
120
126
{
121
127
system_rtc_mem_read (0 , &rst_info, sizeof (rst_info));
122
128
if (rst_info.reason != REASON_SOFT_WDT_RST &&
@@ -127,23 +133,23 @@ void __wrap_system_restart_local() {
127
133
}
128
134
}
129
135
else
130
- rst_info.reason = s_user_reset_reason ;
136
+ rst_info.reason = s_pm. user_reset_reason ;
131
137
132
138
ets_install_putc1 (&uart_write_char_d);
133
139
134
140
cut_here ();
135
141
136
- if (s_panic_line ) {
137
- ets_printf_P (PSTR (" \n Panic %S:%d %S" ), s_panic_file, s_panic_line, s_panic_func );
138
- if (s_panic_what ) {
139
- ets_printf_P (PSTR (" : Assertion '%S' failed." ), s_panic_what );
142
+ if (s_pm. panic_line ) {
143
+ ets_printf_P (PSTR (" \n Panic %S:%d %S" ), s_pm. panic_file , s_pm. panic_line , s_pm. panic_func );
144
+ if (s_pm. panic_what ) {
145
+ ets_printf_P (PSTR (" : Assertion '%S' failed." ), s_pm. panic_what );
140
146
}
141
147
ets_putc (' \n ' );
142
148
}
143
- else if (s_unhandled_exception ) {
144
- ets_printf_P (PSTR (" \n Unhandled C++ exception: %S\n " ), s_unhandled_exception );
149
+ else if (s_pm. unhandled_exception ) {
150
+ ets_printf_P (PSTR (" \n Unhandled C++ exception: %S\n " ), s_pm. unhandled_exception );
145
151
}
146
- else if (s_abort_called ) {
152
+ else if (s_pm. abort_called ) {
147
153
ets_printf_P (PSTR (" \n Abort called\n " ));
148
154
}
149
155
else if (rst_info.reason == REASON_EXCEPTION_RST) {
@@ -159,8 +165,8 @@ void __wrap_system_restart_local() {
159
165
else if (rst_info.reason == REASON_USER_STACK_SMASH) {
160
166
ets_printf_P (PSTR (" \n Stack smashing detected.\n " ));
161
167
ets_printf_P (PSTR (" \n Exception (%d):\n epc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n " ),
162
- 5 /* Alloca exception, closest thing to stack fault*/ , s_stacksmash_addr , 0 , 0 , 0 , 0 );
163
- }
168
+ 5 /* Alloca exception, closest thing to stack fault*/ , s_pm. stacksmash_addr , 0 , 0 , 0 , 0 );
169
+ }
164
170
else {
165
171
ets_printf_P (PSTR (" \n Generic Reset\n " ));
166
172
}
@@ -211,22 +217,22 @@ void __wrap_system_restart_local() {
211
217
ets_printf_P (PSTR (" <<<stack<<<\n " ));
212
218
213
219
// Use cap-X formatting to ensure the standard EspExceptionDecoder doesn't match the address
214
- if (umm_last_fail_alloc_addr ) {
220
+ if (_umm_last_fail_alloc. addr ) {
215
221
#if defined(DEBUG_ESP_OOM)
216
222
ets_printf_P (PSTR (" \n last failed alloc call: %08X(%d)@%S:%d\n " ),
217
- (uint32_t )umm_last_fail_alloc_addr, umm_last_fail_alloc_size ,
218
- umm_last_fail_alloc_file, umm_last_fail_alloc_line );
223
+ (uint32_t )_umm_last_fail_alloc. addr , _umm_last_fail_alloc. size ,
224
+ _umm_last_fail_alloc. file , _umm_last_fail_alloc. line );
219
225
#else
220
- ets_printf_P (PSTR (" \n last failed alloc call: %08X(%d)\n " ), (uint32_t )umm_last_fail_alloc_addr, umm_last_fail_alloc_size );
226
+ ets_printf_P (PSTR (" \n last failed alloc call: %08X(%d)\n " ), (uint32_t )_umm_last_fail_alloc. addr , _umm_last_fail_alloc. size );
221
227
#endif
222
228
}
223
229
224
230
cut_here ();
225
231
226
- if (s_unhandled_exception && umm_last_fail_alloc_addr ) {
232
+ if (s_pm. unhandled_exception && _umm_last_fail_alloc. addr ) {
227
233
// now outside from the "cut-here" zone, print correctly the `new` caller address,
228
234
// idf-monitor.py will be able to decode this one and show exact location in sources
229
- ets_printf_P (PSTR (" \n last failed alloc caller: 0x%08x\n " ), (uint32_t )umm_last_fail_alloc_addr );
235
+ ets_printf_P (PSTR (" \n last failed alloc caller: 0x%08x\n " ), (uint32_t )_umm_last_fail_alloc. addr );
230
236
}
231
237
232
238
custom_crash_callback ( &rst_info, sp_dump + offset, stack_end );
@@ -275,45 +281,45 @@ static void raise_exception() {
275
281
if (gdb_present ())
276
282
__asm__ __volatile__ (" syscall" ); // triggers GDB when enabled
277
283
278
- s_user_reset_reason = REASON_USER_SWEXCEPTION_RST;
284
+ s_pm. user_reset_reason = REASON_USER_SWEXCEPTION_RST;
279
285
ets_printf_P (PSTR (" \n User exception (panic/abort/assert)" ));
280
286
__wrap_system_restart_local ();
281
287
282
288
while (1 ); // never reached, needed to satisfy "noreturn" attribute
283
289
}
284
290
285
291
void abort () {
286
- s_abort_called = true ;
292
+ s_pm. abort_called = true ;
287
293
raise_exception ();
288
294
}
289
295
290
296
void __unhandled_exception (const char *str) {
291
- s_unhandled_exception = str;
297
+ s_pm. unhandled_exception = str;
292
298
raise_exception ();
293
299
}
294
300
295
301
void __assert_func (const char *file, int line, const char *func, const char *what) {
296
- s_panic_file = file;
297
- s_panic_line = line;
298
- s_panic_func = func;
299
- s_panic_what = what;
302
+ s_pm. panic_file = file;
303
+ s_pm. panic_line = line;
304
+ s_pm. panic_func = func;
305
+ s_pm. panic_what = what;
300
306
gdb_do_break (); /* if GDB is not present, this is a no-op */
301
307
raise_exception ();
302
308
}
303
309
304
310
void __panic_func (const char * file, int line, const char * func) {
305
- s_panic_file = file;
306
- s_panic_line = line;
307
- s_panic_func = func;
308
- s_panic_what = 0 ;
311
+ s_pm. panic_file = file;
312
+ s_pm. panic_line = line;
313
+ s_pm. panic_func = func;
314
+ s_pm. panic_what = 0 ;
309
315
gdb_do_break (); /* if GDB is not present, this is a no-op */
310
316
raise_exception ();
311
317
}
312
318
313
319
uintptr_t __stack_chk_guard = 0x08675309 ^ RANDOM_REG32;
314
320
void __stack_chk_fail (void ) {
315
- s_user_reset_reason = REASON_USER_STACK_SMASH;
316
- s_stacksmash_addr = (uint32_t )__builtin_return_address (0 );
321
+ s_pm. user_reset_reason = REASON_USER_STACK_SMASH;
322
+ s_pm. stacksmash_addr = (uint32_t )__builtin_return_address (0 );
317
323
318
324
if (gdb_present ())
319
325
__asm__ __volatile__ (" syscall" ); // triggers GDB when enabled
0 commit comments