Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gdb: xtensa: fix backtrace interrupted by a noreturn call
This commit fixes an issue that the backtrace will be interrupted on a frame where a noreturn function is called. This issue doesn't occur for every call to noreturn functions, but only for calls such that: - the call is the last instruction of the caller function - the next function starts immediately after this call instruction; in most cases this means that the caller function size is divisible by 4 bytes, so no padding is added between the last instruction and the next function. For example, the following generated code will exhibit this issue: esp_system_abort: entry a1, 32 movi.n a10, a2 call8 panic_abort some_other_function: entry a1, 32 ... In this case, esp_system_abort function is 3 + 2 + 3 = 8 bytes long, so no padding is required before "some_other_function". When the call to panic_abort happens, the return address is set to the next instruction, i.e. the "entry" instruction of "some_other_function". The observed behavior is that the backtrace is interrupted: #0 panic_abort (details=0x3ffb5c3b "abort() was called at PC 0x400d485f on core 0") at $IDF_PATH/components/esp_system/panic.c:389 #1 0x40084fb0 in esp_system_abort ( details=0x3ffb5c3b "abort() was called at PC 0x400d485f on core 0") at $IDF_PATH/components/esp_system/esp_system.c:129 Backtrace stopped: previous frame identical to this frame (corrupt stack?) The reason is that when the unwinder inspects the instruction at the return address in the caller frame, the instruction is an ENTRY, which is part of the next function. Previously it was considered that the only case when this can happen is if the frame is the outermost frame and the entry instruction hasn't executed yet. This commit fixes that assumption, by checking additionally if the instruction preceding ENTRY is a call. If it is, the frame is handled as usual.
- Loading branch information