mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 14:44:32 +02:00
esp_system: remove duplicate panic backtrace code
This commit is contained in:
@@ -87,6 +87,24 @@ extern void esp_backtrace_get_start(uint32_t *pc, uint32_t *sp, uint32_t *next_p
|
|||||||
*/
|
*/
|
||||||
bool esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame);
|
bool esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print the backtrace from specified frame.
|
||||||
|
*
|
||||||
|
* @param depth The maximum number of stack frames to print (should be > 0)
|
||||||
|
* @param frame Starting frame to print from
|
||||||
|
* @param panic Indicator if backtrace print is during a system panic
|
||||||
|
*
|
||||||
|
* @note On the ESP32, users must call esp_backtrace_get_start() first to flush the stack.
|
||||||
|
* @note If a esp_backtrace_frame_t* frame is obtained though a call to esp_backtrace_get_start()
|
||||||
|
* from some example function func_a(), then frame is only valid within the frame/scope of func_a().
|
||||||
|
* Users should not attempt to pass/use frame other frames within the same stack of different stacks.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK Backtrace successfully printed to completion or to depth limit
|
||||||
|
* - ESP_FAIL Backtrace is corrupted
|
||||||
|
*/
|
||||||
|
esp_err_t IRAM_ATTR esp_backtrace_print_from_frame(int depth, const esp_backtrace_frame_t* frame, bool panic);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print the backtrace of the current stack
|
* @brief Print the backtrace of the current stack
|
||||||
*
|
*
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_types.h"
|
#include "esp_types.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
#include "esp_debug_helpers.h"
|
#include "esp_debug_helpers.h"
|
||||||
#include "soc/soc_memory_layout.h"
|
#include "soc/soc_memory_layout.h"
|
||||||
#include "soc/cpu.h"
|
#include "soc/cpu.h"
|
||||||
|
#include "esp_private/panic_internal.h"
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
@@ -36,7 +39,28 @@ bool IRAM_ATTR esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame)
|
|||||||
return (esp_stack_ptr_is_sane(frame->sp) && esp_ptr_executable((void*)esp_cpu_process_stack_pc(frame->pc)));
|
return (esp_stack_ptr_is_sane(frame->sp) && esp_ptr_executable((void*)esp_cpu_process_stack_pc(frame->pc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
|
static void IRAM_ATTR print_entry(uint32_t pc, uint32_t sp, bool panic)
|
||||||
|
{
|
||||||
|
if (panic) {
|
||||||
|
panic_print_str("0x");
|
||||||
|
panic_print_hex(pc);
|
||||||
|
panic_print_str(":0x");
|
||||||
|
panic_print_hex(sp);
|
||||||
|
} else {
|
||||||
|
esp_rom_printf("0x%08X:0x%08X", pc, sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IRAM_ATTR print_str(const char* str, bool panic)
|
||||||
|
{
|
||||||
|
if (panic) {
|
||||||
|
panic_print_str(str);
|
||||||
|
} else {
|
||||||
|
esp_rom_printf(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t IRAM_ATTR esp_backtrace_print_from_frame(int depth, const esp_backtrace_frame_t* frame, bool panic)
|
||||||
{
|
{
|
||||||
//Check arguments
|
//Check arguments
|
||||||
if (depth <= 0) {
|
if (depth <= 0) {
|
||||||
@@ -44,11 +68,11 @@ esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Initialize stk_frame with first frame of stack
|
//Initialize stk_frame with first frame of stack
|
||||||
esp_backtrace_frame_t stk_frame;
|
esp_backtrace_frame_t stk_frame = { 0 };
|
||||||
esp_backtrace_get_start(&(stk_frame.pc), &(stk_frame.sp), &(stk_frame.next_pc));
|
memcpy(&stk_frame, frame, sizeof(esp_backtrace_frame_t));
|
||||||
//esp_cpu_get_backtrace_start(&stk_frame);
|
|
||||||
esp_rom_printf("\r\n\r\nBacktrace:");
|
print_str("\r\n\r\nBacktrace:", panic);
|
||||||
esp_rom_printf("0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
print_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp, panic);
|
||||||
|
|
||||||
//Check if first frame is valid
|
//Check if first frame is valid
|
||||||
bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) &&
|
bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) &&
|
||||||
@@ -60,17 +84,26 @@ esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
|
|||||||
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get previous stack frame
|
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get previous stack frame
|
||||||
corrupted = true;
|
corrupted = true;
|
||||||
}
|
}
|
||||||
esp_rom_printf("0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
print_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp, panic);
|
||||||
|
print_str(" ", panic);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Print backtrace termination marker
|
//Print backtrace termination marker
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
if (corrupted) {
|
if (corrupted) {
|
||||||
esp_rom_printf(" |<-CORRUPTED");
|
print_str(" |<-CORRUPTED", panic);
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
} else if (stk_frame.next_pc != 0) { //Backtrace continues
|
} else if (stk_frame.next_pc != 0) { //Backtrace continues
|
||||||
esp_rom_printf(" |<-CONTINUES");
|
print_str(" |<-CONTINUES", panic);
|
||||||
}
|
}
|
||||||
esp_rom_printf("\r\n\r\n");
|
print_str("\r\n\r\n", panic);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
|
||||||
|
{
|
||||||
|
//Initialize stk_frame with first frame of stack
|
||||||
|
esp_backtrace_frame_t start;
|
||||||
|
esp_backtrace_get_start(&(start.pc), &(start.sp), &(start.next_pc));
|
||||||
|
return esp_backtrace_print_from_frame(depth, &start, false);
|
||||||
|
}
|
||||||
|
@@ -444,14 +444,6 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_backtrace_entry(uint32_t pc, uint32_t sp)
|
|
||||||
{
|
|
||||||
panic_print_str("0x");
|
|
||||||
panic_print_hex(pc);
|
|
||||||
panic_print_str(":0x");
|
|
||||||
panic_print_hex(sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t panic_get_address(const void* f)
|
uint32_t panic_get_address(const void* f)
|
||||||
{
|
{
|
||||||
return ((XtExcFrame*)f)->pc;
|
return ((XtExcFrame*)f)->pc;
|
||||||
@@ -469,34 +461,7 @@ void panic_set_address(void *f, uint32_t addr)
|
|||||||
|
|
||||||
void panic_print_backtrace(const void *f, int core)
|
void panic_print_backtrace(const void *f, int core)
|
||||||
{
|
{
|
||||||
// [refactor-todo] once debug helpers have support for both xtensa and riscv, move to
|
XtExcFrame *xt_frame = (XtExcFrame *) f;
|
||||||
// common panic_handler.c
|
esp_backtrace_frame_t frame = {.pc = xt_frame->pc, .sp = xt_frame->a1, .next_pc = xt_frame->a0};
|
||||||
XtExcFrame *frame = (XtExcFrame *) f;
|
esp_backtrace_print_from_frame(100, &frame, true);
|
||||||
int depth = 100;
|
|
||||||
//Initialize stk_frame with first frame of stack
|
|
||||||
esp_backtrace_frame_t stk_frame = {.pc = frame->pc, .sp = frame->a1, .next_pc = frame->a0};
|
|
||||||
panic_print_str("\r\nBacktrace:");
|
|
||||||
print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
|
||||||
|
|
||||||
//Check if first frame is valid
|
|
||||||
bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) &&
|
|
||||||
(esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) ||
|
|
||||||
/* Ignore the first corrupted PC in case of InstrFetchProhibited */
|
|
||||||
frame->exccause == EXCCAUSE_INSTR_PROHIBITED));
|
|
||||||
|
|
||||||
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
|
|
||||||
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
|
|
||||||
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame
|
|
||||||
corrupted = true;
|
|
||||||
}
|
|
||||||
panic_print_str(" ");
|
|
||||||
print_backtrace_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Print backtrace termination marker
|
|
||||||
if (corrupted) {
|
|
||||||
panic_print_str(" |<-CORRUPTED");
|
|
||||||
} else if (stk_frame.next_pc != 0) { //Backtrace continues
|
|
||||||
panic_print_str(" |<-CONTINUES");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user