emergency handlers: always save SP _at_ the crash location
Save SP which is closest to the crash location, which simplifies debugging. For serial_dump, write SP just before the dump. For xfdump, save SP in the dump header. This makes xfdump_dump and xfdump_full_dump_and_reset() equivalent for stack debugging.
This commit is contained in:
parent
96aad0a475
commit
928c7211ad
|
|
@ -932,11 +932,11 @@ void dcode_9125()
|
|||
void dcode_20()
|
||||
{
|
||||
if(code_seen('E'))
|
||||
xfdump_full_dump_and_reset();
|
||||
xfdump_full_dump_and_reset(SP);
|
||||
else
|
||||
{
|
||||
unsigned long ts = _millis();
|
||||
xfdump_dump();
|
||||
xfdump_dump(SP);
|
||||
ts = _millis() - ts;
|
||||
DBG(_N("dump completed in %lums\n"), ts);
|
||||
}
|
||||
|
|
@ -971,7 +971,7 @@ void dcode_22()
|
|||
|
||||
bool emergency_serial_dump = false;
|
||||
|
||||
void serial_dump_and_reset(dump_crash_reason reason)
|
||||
void serial_dump_and_reset(uint16_t sp, dump_crash_reason reason)
|
||||
{
|
||||
// we're being called from a live state, so shut off interrupts and heaters
|
||||
cli();
|
||||
|
|
@ -982,7 +982,9 @@ void serial_dump_and_reset(dump_crash_reason reason)
|
|||
// this function can also be called from within a corrupted state, so not use
|
||||
// printf family of functions that use the heap or grow the stack.
|
||||
SERIAL_ECHOLNPGM("D23 - emergency serial dump");
|
||||
SERIAL_ECHOPGM("reason: ");
|
||||
SERIAL_ECHOPGM("exception: ");
|
||||
SERIAL_ECHO(sp);
|
||||
SERIAL_ECHO(" ");
|
||||
SERIAL_ECHOLN((unsigned)reason);
|
||||
|
||||
// set WDT long enough to allow writing the entire stream
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ extern void dcode_22(); //D22 - Clear crash dump state
|
|||
#ifdef EMERGENCY_SERIAL_DUMP
|
||||
#include "xflash_dump.h"
|
||||
extern bool emergency_serial_dump;
|
||||
extern void serial_dump_and_reset(dump_crash_reason);
|
||||
extern void serial_dump_and_reset(uint16_t sp, dump_crash_reason);
|
||||
#endif
|
||||
|
||||
#ifdef HEATBED_ANALYSIS
|
||||
|
|
|
|||
|
|
@ -1716,15 +1716,15 @@ void setup()
|
|||
}
|
||||
|
||||
|
||||
static inline void crash_and_burn(dump_crash_reason reason)
|
||||
static inline void crash_and_burn(uint16_t sp, dump_crash_reason reason)
|
||||
{
|
||||
WRITE(BEEPER, HIGH);
|
||||
eeprom_update_byte((uint8_t*)EEPROM_FW_CRASH_FLAG, (uint8_t)reason);
|
||||
#ifdef EMERGENCY_DUMP
|
||||
xfdump_full_dump_and_reset(reason);
|
||||
xfdump_full_dump_and_reset(sp, reason);
|
||||
#elif defined(EMERGENCY_SERIAL_DUMP)
|
||||
if(emergency_serial_dump)
|
||||
serial_dump_and_reset(reason);
|
||||
serial_dump_and_reset(sp, reason);
|
||||
#endif
|
||||
softReset();
|
||||
}
|
||||
|
|
@ -1733,18 +1733,18 @@ static inline void crash_and_burn(dump_crash_reason reason)
|
|||
#ifdef WATCHDOG
|
||||
ISR(WDT_vect)
|
||||
{
|
||||
crash_and_burn(dump_crash_reason::watchdog);
|
||||
crash_and_burn(SP, dump_crash_reason::watchdog);
|
||||
}
|
||||
#endif
|
||||
|
||||
ISR(BADISR_vect)
|
||||
{
|
||||
crash_and_burn(dump_crash_reason::bad_isr);
|
||||
crash_and_burn(SP, dump_crash_reason::bad_isr);
|
||||
}
|
||||
#endif //EMERGENCY_HANDLERS
|
||||
|
||||
void stack_error() {
|
||||
crash_and_burn(dump_crash_reason::stack_error);
|
||||
crash_and_burn(SP, dump_crash_reason::stack_error);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1807,7 +1807,7 @@ static void lcd_preheat_menu()
|
|||
static void lcd_dump_memory()
|
||||
{
|
||||
lcd_beeper_quick_feedback();
|
||||
xfdump_dump();
|
||||
xfdump_dump(SP);
|
||||
lcd_return_to_status();
|
||||
}
|
||||
#endif //MENU_DUMP
|
||||
|
|
@ -1816,7 +1816,7 @@ static void lcd_dump_memory()
|
|||
|
||||
static void lcd_serial_dump()
|
||||
{
|
||||
serial_dump_and_reset(dump_crash_reason::manual);
|
||||
serial_dump_and_reset(SP, dump_crash_reason::manual);
|
||||
}
|
||||
#endif //MENU_SERIAL_DUMP
|
||||
|
||||
|
|
|
|||
|
|
@ -68,12 +68,13 @@ static void xfdump_dump_core(dump_header_t& hdr, uint32_t addr, uint8_t* buf, ui
|
|||
}
|
||||
|
||||
|
||||
void xfdump_dump()
|
||||
void xfdump_dump(uint16_t sp)
|
||||
{
|
||||
dump_header_t buf;
|
||||
buf.magic = DUMP_MAGIC;
|
||||
buf.regs_present = false;
|
||||
buf.crash_reason = (uint8_t)dump_crash_reason::manual;
|
||||
buf.sp = sp;
|
||||
|
||||
// write sram only
|
||||
xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data.sram),
|
||||
|
|
@ -81,12 +82,13 @@ void xfdump_dump()
|
|||
}
|
||||
|
||||
|
||||
void xfdump_full_dump_and_reset(dump_crash_reason reason)
|
||||
void xfdump_full_dump_and_reset(uint16_t sp, dump_crash_reason reason)
|
||||
{
|
||||
dump_header_t buf;
|
||||
buf.magic = DUMP_MAGIC;
|
||||
buf.regs_present = true;
|
||||
buf.crash_reason = (uint8_t)reason;
|
||||
buf.sp = sp;
|
||||
|
||||
// disable interrupts for a cleaner register dump
|
||||
cli();
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ enum class dump_crash_reason : uint8_t
|
|||
};
|
||||
|
||||
#ifdef XFLASH_DUMP
|
||||
void xfdump_reset(); // reset XFLASH dump state
|
||||
void xfdump_dump(); // create a new SRAM memory dump
|
||||
void xfdump_reset(); // reset XFLASH dump state
|
||||
void xfdump_dump(uint16_t sp); // create a new SRAM memory dump
|
||||
|
||||
// return true if a dump is present, save type in "reason" if provided
|
||||
bool xfdump_check_state(dump_crash_reason* reason = NULL);
|
||||
|
||||
// create a new dump containing registers and SRAM, then reset
|
||||
void xfdump_full_dump_and_reset(dump_crash_reason crash = dump_crash_reason::manual);
|
||||
void xfdump_full_dump_and_reset(
|
||||
uint16_t sp, dump_crash_reason crash = dump_crash_reason::manual);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct dump_header_t
|
|||
|
||||
uint8_t regs_present; // true when the lower segment containing registers is present
|
||||
uint8_t crash_reason; // uses values from dump_crash_source
|
||||
uint16_t sp; // SP closest to the crash location
|
||||
};
|
||||
|
||||
struct dump_data_t
|
||||
|
|
|
|||
Loading…
Reference in New Issue