1
0
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:
armink 2020-03-12 15:23:25 +08:00
parent 9b1158bf12
commit f60c1c48e0
2 changed files with 27 additions and 4 deletions

View File

@ -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;

View File

@ -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