diff --git a/components/esp32/test/test_backtrace.c b/components/esp32/test/test_backtrace.c index 2c1f4d8737..1520a8dde0 100644 --- a/components/esp32/test/test_backtrace.c +++ b/components/esp32/test/test_backtrace.c @@ -69,3 +69,15 @@ TEST_CASE("Test backtrace from interrupt watchdog timeout", "[reset_reason][rese backtrace_trigger_source = ACTION_INT_WDT; recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_1); //Trigger lvl 1 SW interrupt at max recursive depth } + +static void write_char_crash(char c) +{ + ets_write_char_uart(c); + *(char*) 0x00000001 = 0; +} + +TEST_CASE("Test backtrace with a ROM function", "[reset_reason][reset=StoreProhibited,SW_CPU_RESET]") +{ + ets_install_putc1(&write_char_crash); + ets_printf("foo"); +} diff --git a/components/heap/include/heap_trace.inc b/components/heap/include/heap_trace.inc index a51b07a6ab..38285f131b 100644 --- a/components/heap/include/heap_trace.inc +++ b/components/heap/include/heap_trace.inc @@ -26,6 +26,15 @@ inline static uint32_t get_ccount(void) return ccount; } +/* Architecture-specific return value of __builtin_return_address which + * should be interpreted as an invalid address. + */ +#ifdef __XTENSA__ +#define HEAP_ARCH_INVALID_PC 0x40000000 +#else +#define HEAP_ARCH_INVALID_PC 0x00000000 +#endif + // Caller is 2 stack frames deeper than we care about #define STACK_OFFSET 2 @@ -33,8 +42,9 @@ inline static uint32_t get_ccount(void) if (STACK_DEPTH == N) { \ return; \ } \ - callers[N] = __builtin_return_address(N+STACK_OFFSET); \ - if (!esp_ptr_executable(callers[N])) { \ + callers[N] = __builtin_return_address(N+STACK_OFFSET); \ + if (!esp_ptr_executable(callers[N]) \ + || callers[N] == (void*) HEAP_ARCH_INVALID_PC) { \ return; \ } \ } while(0)