Przeglądaj źródła

heap: recognize 0x40000000 as an address terminating the backtrace

On Xtensa, backtrace can not recover the two most significant bits of
the address, as the window call size is encoded in these bits.
Because of this, __builtin_return_address modifies these MSBs to
match those of the callee, "fixing" the address. An unfortunate side
effect is that the zero return address, which usually terminates the
backtrace, gets converted to 0x40000000. While there is a valid
instruction at this address, its occurrence in the backtrace is
highly unlikely: this is the first instruction of WindowOverflow4
vector, and IDF apps switch VECBASE to an IRAM location very early at
startup.
Ivan Grokhotkov 6 lat temu
rodzic
commit
b4aba189ab
1 zmienionych plików z 12 dodań i 2 usunięć
  1. 12 2
      components/heap/include/heap_trace.inc

+ 12 - 2
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) {            \
             callers[N] = 0;                                             \
             return;                                                     \
         }                                                               \