Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 326be35

Browse filesBrowse files
authored
Postmortem improvements (esp8266#8839)
* divide by 0 reporting to point back at the divide function caller * stack offset adjustments to be independent of __wrap_system_restart_local()'s stack frame size.
1 parent 1beca6f commit 326be35
Copy full SHA for 326be35

File tree

Expand file treeCollapse file tree

1 file changed

+55
-13
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+55
-13
lines changed

‎cores/esp8266/core_esp8266_postmortem.cpp

Copy file name to clipboardExpand all lines: cores/esp8266/core_esp8266_postmortem.cpp
+55-13Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,26 @@ static void cut_here() {
110110
ets_putc('\n');
111111
}
112112

113-
void __wrap_system_restart_local() {
114-
register uint32_t sp asm("a1");
115-
uint32_t sp_dump = sp;
116-
113+
/*
114+
Add some assembly to grab the stack pointer and pass it as an argument before
115+
it grows for the target function. Should stabilize the stack offsets, used to
116+
find the relevant stack content for dumping.
117+
*/
118+
extern "C" void __wrap_system_restart_local(void);
119+
asm(
120+
".section .text.__wrap_system_restart_local,\"ax\",@progbits\n\t"
121+
".literal_position\n\t"
122+
".align 4\n\t"
123+
".global __wrap_system_restart_local\n\t"
124+
".type __wrap_system_restart_local, @function\n\t"
125+
"\n"
126+
"__wrap_system_restart_local:\n\t"
127+
"mov a2, a1\n\t"
128+
"j postmortem_report\n\t"
129+
".size __wrap_system_restart_local, .-__wrap_system_restart_local\n\t"
130+
);
131+
132+
static void postmortem_report(uint32_t sp_dump) {
117133
struct rst_info rst_info;
118134
memset(&rst_info, 0, sizeof(rst_info));
119135
if (s_user_reset_reason == REASON_DEFAULT_RST)
@@ -152,9 +168,17 @@ void __wrap_system_restart_local() {
152168
else if (rst_info.reason == REASON_EXCEPTION_RST) {
153169
// The GCC divide routine in ROM jumps to the address below and executes ILL (00 00 00) on div-by-zero
154170
// In that case, print the exception as (6) which is IntegerDivZero
155-
bool div_zero = (rst_info.exccause == 0) && (rst_info.epc1 == 0x4000dce5);
171+
uint32_t epc1 = rst_info.epc1;
172+
uint32_t exccause = rst_info.exccause;
173+
bool div_zero = (exccause == 0) && (epc1 == 0x4000dce5u);
174+
if (div_zero) {
175+
exccause = 6;
176+
// In place of the detached 'ILL' instruction., redirect attention
177+
// back to the code that called the ROM divide function.
178+
__asm__ __volatile__("rsr.excsave1 %0\n\t" : "=r"(epc1) :: "memory");
179+
}
156180
ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"),
157-
div_zero ? 6 : rst_info.exccause, rst_info.epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc);
181+
exccause, epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc);
158182
}
159183
else if (rst_info.reason == REASON_SOFT_WDT_RST) {
160184
ets_printf_P(PSTR("\nSoft WDT reset\n"));
@@ -174,16 +198,31 @@ void __wrap_system_restart_local() {
174198

175199
// amount of stack taken by interrupt or exception handler
176200
// and everything up to __wrap_system_restart_local
177-
// (determined empirically, might break)
201+
// ~(determined empirically, might break)~
178202
uint32_t offset = 0;
179203
if (rst_info.reason == REASON_SOFT_WDT_RST) {
180-
offset = 0x1a0;
204+
// Stack Tally
205+
// 256 User Exception vector handler reserves stack space
206+
// directed to _xtos_l1int_handler function in Boot ROM
207+
// 48 wDev_ProcessFiq - its address appears in a vector table at 0x3FFFC27C
208+
// 16 ?unnamed? - index into a table, pull out pointer, and call if non-zero
209+
// appears near near wDev_ProcessFiq
210+
// 32 pp_soft_wdt_feed_local - gather the specifics and call __wrap_system_restart_local
211+
offset = 32 + 16 + 48 + 256;
181212
}
182213
else if (rst_info.reason == REASON_EXCEPTION_RST) {
183-
offset = 0x190;
214+
// Stack Tally
215+
// 256 Exception vector reserves stack space
216+
// filled in by "C" wrapper handler
217+
// 16 Handler level 1 - enable icache
218+
// 64 Handler level 2 - exception report
219+
offset = 64 + 16 + 256;
184220
}
185221
else if (rst_info.reason == REASON_WDT_RST) {
186-
offset = 0x10;
222+
offset = 16;
223+
}
224+
else if (rst_info.reason == REASON_USER_SWEXCEPTION_RST) {
225+
offset = 16;
187226
}
188227

189228
ets_printf_P(PSTR("\n>>>stack>>>\n"));
@@ -280,8 +319,9 @@ static void raise_exception() {
280319

281320
s_user_reset_reason = REASON_USER_SWEXCEPTION_RST;
282321
ets_printf_P(PSTR("\nUser exception (panic/abort/assert)"));
283-
__wrap_system_restart_local();
284-
322+
uint32_t sp;
323+
__asm__ __volatile__ ("mov %0, a1\n\t" : "=r"(sp) :: "memory");
324+
postmortem_report(sp);
285325
while (1); // never reached, needed to satisfy "noreturn" attribute
286326
}
287327

@@ -321,7 +361,9 @@ void __stack_chk_fail(void) {
321361
if (gdb_present())
322362
__asm__ __volatile__ ("syscall"); // triggers GDB when enabled
323363

324-
__wrap_system_restart_local();
364+
uint32_t sp;
365+
__asm__ __volatile__ ("mov %0, a1\n\t" : "=r"(sp) :: "memory");
366+
postmortem_report(sp);
325367

326368
__builtin_unreachable(); // never reached, needed to satisfy "noreturn" attribute
327369
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.