From 4591679ad0fe12f9e6ac2ec0914fe9404b5581e2 Mon Sep 17 00:00:00 2001 From: armink Date: Fri, 30 Dec 2016 11:49:04 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E6=A0=88=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=8F=90=E5=8D=87=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E7=9A=84=E5=87=86=E7=A1=AE=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- cm_backtrace/cm_backtrace.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cm_backtrace/cm_backtrace.c b/cm_backtrace/cm_backtrace.c index cd62549..1612abc 100644 --- a/cm_backtrace/cm_backtrace.c +++ b/cm_backtrace/cm_backtrace.c @@ -317,12 +317,20 @@ static void dump_main_stack(uint32_t stack_start_addr, size_t stack_size, uint32 * @return depth */ size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) { - uint32_t stack_start_addr = main_stack_start_addr, stack_size = main_stack_size; + uint32_t stack_start_addr = main_stack_start_addr, stack_size = main_stack_size, pc; size_t depth = 0; + bool regs_saved_lr_is_valid = false; if (on_fault) { /* 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); + if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH) + && (depth < size)) { + buffer[depth++] = pc; + regs_saved_lr_is_valid = true; + } #ifdef CMB_USING_OS_PLATFORM /* program is running on thread before fault */ @@ -340,10 +348,15 @@ size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) { /* copy called function address */ for (; sp < stack_start_addr + stack_size; sp += sizeof(size_t)) { - if ((*((uint32_t *) sp) >= code_start_addr) && (*((uint32_t *) sp) <= code_start_addr + code_size) - && (depth < CMB_CALL_STACK_MAX_DEPTH) && (depth < size)) { - /* this get value maybe LR, so need decrease a word to PC */ - buffer[depth++] = *((uint32_t *) sp) - sizeof(size_t); + /* the *sp value may be LR, so need decrease a word to PC */ + pc = *((uint32_t *) sp) - sizeof(size_t); + if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH) + && (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; } }