From 059c34c90baf4b9a23b585deca8422a464a234d2 Mon Sep 17 00:00:00 2001 From: jesven Date: Thu, 2 Jun 2022 09:14:08 +0800 Subject: [PATCH] add aarch64 backtrace support --- libcpu/aarch64/common/backtrace.c | 57 +++++++++++++++++++++++++++++++ libcpu/aarch64/common/backtrace.h | 22 ++++++++++++ libcpu/aarch64/common/trap.c | 3 ++ 3 files changed, 82 insertions(+) create mode 100644 libcpu/aarch64/common/backtrace.c create mode 100644 libcpu/aarch64/common/backtrace.h diff --git a/libcpu/aarch64/common/backtrace.c b/libcpu/aarch64/common/backtrace.c new file mode 100644 index 0000000000..c3e3803f93 --- /dev/null +++ b/libcpu/aarch64/common/backtrace.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-06-02 Jesven the first version + */ + +#include +#include + +#define BT_NESTING_MAX 100 + +static int unwind_frame(struct bt_frame *frame) +{ + unsigned long fp = frame->fp; + + if ((fp & 0x7) +#ifdef RT_USING_LWP + || fp < KERNEL_VADDR_START +#endif + ) + { + return 1; + } + frame->fp = *(unsigned long *)fp; + frame->pc = *(unsigned long *)(fp + 8); + return 0; +} + +static void walk_unwind(unsigned long pc, unsigned long fp) +{ + struct bt_frame frame; + unsigned long lr = pc; + int nesting = 0; + + frame.fp = fp; + while (nesting < BT_NESTING_MAX) + { + rt_kprintf(" %p", (void *)lr); + if (unwind_frame(&frame)) + { + break; + } + lr = frame.pc; + nesting++; + } +} + +void backtrace(unsigned long pc, unsigned long lr, unsigned long fp) +{ + rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc); + walk_unwind(lr, fp); + rt_kprintf("\n"); +} diff --git a/libcpu/aarch64/common/backtrace.h b/libcpu/aarch64/common/backtrace.h new file mode 100644 index 0000000000..b34601da58 --- /dev/null +++ b/libcpu/aarch64/common/backtrace.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-06-02 Jesven the first version + */ + +#ifndef __BACKTRACE_H__ +#define __BACKTRACE_H__ + +struct bt_frame +{ + unsigned long fp; + unsigned long pc; +}; + +void backtrace(unsigned long pc, unsigned long lr, unsigned long fp); + +#endif /*__BACKTRACE_H__*/ diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c index 103dd6fff4..0a449efeb8 100644 --- a/libcpu/aarch64/common/trap.c +++ b/libcpu/aarch64/common/trap.c @@ -15,6 +15,8 @@ #include #include "interrupt.h" +#include + void rt_unwind(struct rt_hw_exp_stack *regs, int pc_adj) { } @@ -251,6 +253,7 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs) #ifdef RT_USING_FINSH list_thread(); #endif + backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29); rt_hw_cpu_shutdown(); } -- Gitee