armink / CmBacktrace

Advanced fault backtrace library for ARM Cortex-M series MCU | ARM Cortex-M 系列 MCU 错误追踪库
MIT License
1.71k stars 661 forks source link

关于回溯栈指针准确性的问题 #44

Open chenchuangchn opened 3 years ago

chenchuangchn commented 3 years ago

Hi~,Armink:

拜读了您的cmbacktrace代码,在阅读到cm_backtrace_call_stack函数的时候,有两个点不是很理解,请您赐教。代码段如下: / copy called function address / for (; sp < stack_start_addr + stack_size; sp += sizeof(size_t)) { / the sp value may be LR, so need decrease a word to PC / pc = ((uint32_t ) sp) - sizeof(size_t); // ------------------------------------ 1 / the Cortex-M using thumb instruction, so the pc must be an odd number / if (pc % 2 == 0) { continue; } / fix the PC address in thumb mode / pc = ((uint32_t ) sp) - 1; if ((pc >= code_start_addr + sizeof(size_t)) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH) / check the the instruction before PC address is 'BL' or 'BLX' / && disassembly_ins_is_bl_blx(pc - sizeof(size_t)) && (depth < size)) { / the second depth function may be already saved, so need ignore repeat */ if ((depth == 2) && regs_saved_lr_is_valid && (pc == buffer[1])) { continue; } buffer[depth++] = pc; // ------------------------------------- 2 } }

  1. 判断pc的值为啥要减去 sizeof(size_t), 直接判断pc的奇偶不可以吗?
  2. 既然是通过sp里找的,并且是判断pc的上一条指令是不是bl或blx,那显然找的其实是sp里的lr的值。而lr的值是执行执行指令的下一条指令的,所以我理解如上代码的buffer[depth++]里存储的是lr的里的指令值,但是不应该存储pc -4吗?