Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A few things about crash dumps #1795

Closed
JavierAder opened this issue Jun 26, 2019 · 4 comments · Fixed by #2282
Closed

A few things about crash dumps #1795

JavierAder opened this issue Jun 26, 2019 · 4 comments · Fixed by #2282
Labels
enhancement New feature or request

Comments

@JavierAder
Copy link

Hi. a few thing about crash dumps: a little enhancement, one idea and a few questions

  • when command crash is run in terminal.ino crashDump() and crashClear() is executed in crash.ino; if there is no crash the simulated rom gets writed (and commited) anyway; it is not necessary.
    Ok, I think that
void crashClear() {
    uint32_t crash_time = 0xFFFFFFFF;
    EEPROMr.put(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_CRASH_TIME, crash_time);
    EEPROMr.commit();
}

can be replaced by something like:

void crashClear() {
    uint32_t crash_time;
    EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_CRASH_TIME, crash_time);
    if (crash_time == 0xFFFFFFFF) //already cleared, there is nothing to do
           return;
    crash_time = 0xFFFFFFFF;
    EEPROMr.put(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_CRASH_TIME, crash_time);
    EEPROMr.commit();
}
  • crashDump can be modified for conform the format of EspArduinoExpceptionDecoder? https://github.com/me21/EspArduinoExceptionDecoder. There are two field missing (ctx and offset; I don't know what are they for but Decoder requires that) and a few differences is format ("Exception(n):", "sp: xxxxxxxx end: xxxxxx offset: xxxxxxxx", these addresses without the prefix 0x). Or probably add a new command, say crashDecoder() (in terminal.ino under command crashDecoder) and crashDumpDecoder() in crash.ino for doing that.

  • is it possible that crashDump() is doing something wrong? I used dumps in EspArduinoExpceptionDecoder and the results were wrong; you can see it in Crashing in SonOff Pow R2 v2.0 (v 1.13.5) #1752 (comment) (for example, it resolves addresses to non-existent code lines). Ok, possible the problem is xtensa toolchain, not crashDump...

@JavierAder JavierAder added the enhancement New feature or request label Jun 26, 2019
@mcspr
Copy link
Collaborator

mcspr commented Jun 29, 2019

EEPROM class is a pretty small wrapper around basic byte array.
https://github.com/esp8266/Arduino/blob/5a47cab77d396afeb842c9161327f9f4dca7c833/libraries/EEPROM/EEPROM.cpp#L118
https://github.com/esp8266/Arduino/blob/5a47cab77d396afeb842c9161327f9f4dca7c833/libraries/EEPROM/EEPROM.cpp#L107-L111
Commit will do nothing if nothing has changed

Format change might be interesting.
https://github.com/esp8266/Arduino/blob/5a47cab77d396afeb842c9161327f9f4dca7c833/cores/esp8266/core_esp8266_postmortem.cpp#L136-L148
https://github.com/esp8266/Arduino/blob/09826c6d87e54c15422da90f060377c9ef188947/cores/esp8266/core_esp8266_postmortem.c#L85-L97
Offset is exception size + postmortem crash handler stack, but as comment says it may not be precise. But we can just pull exact values from there, both offset and context (see below, SYS is just stack_end == 0x3fffffb0)

Results are likely toolchain problem. You can try adding basic *((int*) 0) = 0; in either Ticker or somewhere in loop, and compare serial output with the recorder.

@JavierAder
Copy link
Author

Excellent!
It is interesting note that if "offset" is incorrectly estimated in __wrap_system_restart_local() we would lose the last function calls or get "non-sense garbage" (in particular parts of stack used by interrup/exception handler); I think that should be possible get the "real" stack in any case, but probably it is hard to do....

@JavierAder
Copy link
Author

Well, probably there are a bug in __wrap_system_restart_local() in core version 2.3.0 (at least); by curiosity I see the assembler for that fuction, and it seems that they don't save the correct stack pointer.
https://github.com/esp8266/Arduino/blob/2.3.0/cores/esp8266/core_esp8266_postmortem.c#L53-L56

void __wrap_system_restart_local() {
    register uint32_t sp asm("a1");

    struct rst_info rst_info = {0};

but in your link (development version?):
https://github.com/esp8266/Arduino/blob/5a47cab77d396afeb842c9161327f9f4dca7c833/cores/esp8266/core_esp8266_postmortem.cpp#L85-L88

void __wrap_system_restart_local() {
    register uint32_t sp asm("a1");
    uint32_t sp_dump = sp;

The problem in version 2.3.0 is that when they later references to var sp , they get the current value of register a1 (stack pointer), BUT it register is modified by __wrap_system_restart_local() it self!:

402015c4 <__wrap_system_restart_local>:
402015c4:	a0c112        	addi	a1, a1, -96
402015c7:	030c      	movi.n	a3, 0
402015c9:	1ca042        	movi	a4, 28

are we getting 96 bytes of non-sense stack?

@JavierAder
Copy link
Author

Well, probably there are a bug in __wrap_system_restart_local() in core version 2.3.0 (at least); ....

mmmmm not, there isn't... "uint32_t sp_dump = sp" don't really change nothing and we don't get 96 bytes non-sense because the offset takes them into account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants