mirror of
https://github.com/armink/CmBacktrace.git
synced 2025-01-25 00:22:53 +08:00
【完善】函数调用栈识别策略,增加 LR 地址更多有效性检测,提升识别准确性。
Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
parent
9b1158bf12
commit
f60c1c48e0
@ -329,6 +329,26 @@ static void dump_stack(uint32_t stack_start_addr, size_t stack_size, uint32_t *s
|
||||
}
|
||||
#endif /* CMB_USING_DUMP_STACK_INFO */
|
||||
|
||||
/* check the disassembly instruction is 'BL' or 'BLX' */
|
||||
static bool disassembly_ins_is_bl_blx(uint32_t addr) {
|
||||
uint16_t ins1 = *((uint16_t *)addr);
|
||||
uint16_t ins2 = *((uint16_t *)(addr + 2));
|
||||
|
||||
#define BL_INS_MASK 0xF800
|
||||
#define BL_INS_HIGH 0xF800
|
||||
#define BL_INS_LOW 0xF000
|
||||
#define BLX_INX_MASK 0xFF00
|
||||
#define BLX_INX 0x4700
|
||||
|
||||
if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW) {
|
||||
return true;
|
||||
} else if ((ins2 & BLX_INX_MASK) == BLX_INX) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* backtrace function call stack
|
||||
*
|
||||
@ -347,8 +367,8 @@ size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) {
|
||||
if (!stack_is_overflow) {
|
||||
/* first depth is PC */
|
||||
buffer[depth++] = regs.saved.pc;
|
||||
/* second depth is from LR, so need decrease a word to PC */
|
||||
pc = regs.saved.lr - sizeof(size_t);
|
||||
/* fix the LR address in thumb mode */
|
||||
pc = regs.saved.lr - 1;
|
||||
if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
|
||||
&& (depth < size)) {
|
||||
buffer[depth++] = pc;
|
||||
@ -386,8 +406,11 @@ size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) {
|
||||
if (pc % 2 == 0) {
|
||||
continue;
|
||||
}
|
||||
/* fix the PC address in thumb mode */
|
||||
pc = *((uint32_t *) sp) - 1;
|
||||
if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
|
||||
&& (depth < size)) {
|
||||
/* 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;
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
/* library software version number */
|
||||
#define CMB_SW_VERSION "1.3.0"
|
||||
#define CMB_SW_VERSION "1.3.99"
|
||||
|
||||
#define CMB_CPU_ARM_CORTEX_M0 0
|
||||
#define CMB_CPU_ARM_CORTEX_M3 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user