@@ -62,32 +62,25 @@ extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack,
6262
6363extern void custom_crash_callback ( struct rst_info * rst_info , uint32_t stack , uint32_t stack_end ) __attribute__ ((weak , alias ("__custom_crash_callback" )));
6464
65- // Single, non-inlined copy of pgm_read_byte to save IRAM space (as this is not timing critical)
66- static char ICACHE_RAM_ATTR iram_read_byte (const char * addr ) {
67- return pgm_read_byte (addr );
68- }
69-
70- // Required to output the s_panic_file, it's stored in PMEM
71- #define ets_puts_P (pstr ) \
72- { \
73- char c; \
74- do { \
75- c = iram_read_byte(pstr++); \
76- if (c) ets_putc(c); \
77- } while (c); \
78- }
7965
80- // Place these strings in .text because the SPI interface may be in bad shape during an exception.
81- #define ets_printf_P (str , ...) \
82- { \
83- static const char istr[] ICACHE_RAM_ATTR = (str); \
84- char mstr[sizeof(str)]; \
85- for (size_t i=0; i < sizeof(str); i++) mstr[i] = iram_read_byte(&istr[i]); \
86- ets_printf(mstr, ##__VA_ARGS__); \
66+ // Prints need to use our library function to allow for file and function
67+ // to be safely accessed from flash. This function encapsulates snprintf()
68+ // [which by definition will 0-terminate] and dumping to the UART
69+ static void ets_printf_P (const char * str , ...) {
70+ char destStr [160 ];
71+ char * c = destStr ;
72+ va_list argPtr ;
73+ va_start (argPtr , str );
74+ vsnprintf (destStr , sizeof (destStr ), str , argPtr );
75+ va_end (argPtr );
76+ while (* c ) {
77+ ets_putc (* (c ++ ));
78+ }
8779}
8880
8981void __wrap_system_restart_local () {
9082 register uint32_t sp asm("a1" );
83+ uint32_t sp_dump = sp ;
9184
9285 if (gdb_present ()) {
9386 /* When GDBStub is present, exceptions are handled by GDBStub,
@@ -110,28 +103,24 @@ void __wrap_system_restart_local() {
110103 ets_install_putc1 (& uart_write_char_d );
111104
112105 if (s_panic_line ) {
113- ets_printf_P ("\nPanic " );
114- ets_puts_P (s_panic_file ); // This is in PROGMEM, need special output because ets_printf can't handle ROM parameters
115- ets_printf_P (":%d %s" , s_panic_line , s_panic_func );
106+ ets_printf_P (PSTR ("\nPanic %S:%d %S" ), s_panic_file , s_panic_line , s_panic_func );
116107 if (s_panic_what ) {
117- ets_printf_P (": Assertion '" );
118- ets_puts_P (s_panic_what ); // This is also in PMEM
119- ets_printf_P ("' failed." );
108+ ets_printf_P (PSTR (": Assertion '%S' failed." ), s_panic_what );
120109 }
121110 ets_putc ('\n' );
122111 }
123112 else if (s_unhandled_exception ) {
124- ets_printf_P ("\nUnhandled exception: %s \n" , s_unhandled_exception );
113+ ets_printf_P (PSTR ( "\nUnhandled C++ exception: %S \n" ) , s_unhandled_exception );
125114 }
126115 else if (s_abort_called ) {
127- ets_printf_P ("\nAbort called\n" );
116+ ets_printf_P (PSTR ( "\nAbort called\n" ) );
128117 }
129118 else if (rst_info .reason == REASON_EXCEPTION_RST ) {
130- ets_printf_P ("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n" ,
119+ ets_printf_P (PSTR ( "\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n" ) ,
131120 rst_info .exccause , rst_info .epc1 , rst_info .epc2 , rst_info .epc3 , rst_info .excvaddr , rst_info .depc );
132121 }
133122 else if (rst_info .reason == REASON_SOFT_WDT_RST ) {
134- ets_printf_P ("\nSoft WDT reset\n" );
123+ ets_printf_P (PSTR ( "\nSoft WDT reset\n" ) );
135124 }
136125
137126 uint32_t cont_stack_start = (uint32_t ) & (g_pcont -> stack );
@@ -152,54 +141,53 @@ void __wrap_system_restart_local() {
152141 offset = 0x10 ;
153142 }
154143
155- ets_printf_P ("\n>>>stack>>>\n" );
144+ ets_printf_P (PSTR ( "\n>>>stack>>>\n" ) );
156145
157- if (sp > stack_thunk_get_stack_bot () && sp <= stack_thunk_get_stack_top ()) {
146+ if (sp_dump > stack_thunk_get_stack_bot () && sp_dump <= stack_thunk_get_stack_top ()) {
158147 // BearSSL we dump the BSSL second stack and then reset SP back to the main cont stack
159- ets_printf_P ("\nctx: bearssl \n" );
160- ets_printf_P ("sp: %08x end: %08x offset: %04x\n" , sp , stack_thunk_get_stack_top (), offset );
161- print_stack (sp + offset , stack_thunk_get_stack_top ());
148+ ets_printf_P (PSTR ("\nctx: bearssl\nsp: %08x end: %08x offset: %04x\n" ), sp_dump , stack_thunk_get_stack_top (), offset );
149+ print_stack (sp_dump + offset , stack_thunk_get_stack_top ());
162150 offset = 0 ; // No offset needed anymore, the exception info was stored in the bssl stack
163- sp = stack_thunk_get_cont_sp ();
151+ sp_dump = stack_thunk_get_cont_sp ();
164152 }
165153
166- if (sp > cont_stack_start && sp < cont_stack_end ) {
167- ets_printf_P ("\nctx: cont \n" );
154+ if (sp_dump > cont_stack_start && sp_dump < cont_stack_end ) {
155+ ets_printf_P (PSTR ( "\nctx: cont\n" ) );
168156 stack_end = cont_stack_end ;
169157 }
170158 else {
171- ets_printf_P ("\nctx: sys \n" );
159+ ets_printf_P (PSTR ( "\nctx: sys\n" ) );
172160 stack_end = 0x3fffffb0 ;
173161 // it's actually 0x3ffffff0, but the stuff below ets_run
174162 // is likely not really relevant to the crash
175163 }
176164
177- ets_printf_P ("sp: %08x end: %08x offset: %04x\n" , sp , stack_end , offset );
165+ ets_printf_P (PSTR ( "sp: %08x end: %08x offset: %04x\n" ), sp_dump , stack_end , offset );
178166
179- print_stack (sp + offset , stack_end );
167+ print_stack (sp_dump + offset , stack_end );
180168
181- ets_printf_P ("<<<stack<<<\n" );
169+ ets_printf_P (PSTR ( "<<<stack<<<\n" ) );
182170
183171 // Use cap-X formatting to ensure the standard EspExceptionDecoder doesn't match the address
184172 if (umm_last_fail_alloc_addr ) {
185- ets_printf_P ("\nlast failed alloc call: %08X(%d)\n" , (uint32_t )umm_last_fail_alloc_addr , umm_last_fail_alloc_size );
173+ ets_printf_P (PSTR ( "\nlast failed alloc call: %08X(%d)\n" ) , (uint32_t )umm_last_fail_alloc_addr , umm_last_fail_alloc_size );
186174 }
187175
188- custom_crash_callback ( & rst_info , sp + offset , stack_end );
176+ custom_crash_callback ( & rst_info , sp_dump + offset , stack_end );
189177
190178 delayMicroseconds (10000 );
191179 __real_system_restart_local ();
192180}
193181
194182
195- static void ICACHE_RAM_ATTR print_stack (uint32_t start , uint32_t end ) {
183+ static void print_stack (uint32_t start , uint32_t end ) {
196184 for (uint32_t pos = start ; pos < end ; pos += 0x10 ) {
197185 uint32_t * values = (uint32_t * )(pos );
198186
199187 // rough indicator: stack frames usually have SP saved as the second word
200188 bool looksLikeStackFrame = (values [2 ] == pos + 0x10 );
201189
202- ets_printf_P ("%08x: %08x %08x %08x %08x %c\n" ,
190+ ets_printf_P (PSTR ( "%08x: %08x %08x %08x %08x %c\n" ) ,
203191 pos , values [0 ], values [1 ], values [2 ], values [3 ], (looksLikeStackFrame )?'<' :' ' );
204192 }
205193}
0 commit comments