From 70a8d1d4656bc678ddada5e56263c9cb4423a623 Mon Sep 17 00:00:00 2001 From: Shell Date: Sat, 21 Oct 2023 20:14:45 +0800 Subject: [kservice] improve backtrace service in kernel (#8144) Signed-off-by: Shell --- components/lwp/arch/aarch64/cortex-a/lwp_arch.c | 25 ++++++++++++++++- components/lwp/arch/risc-v/rv64/lwp_arch.c | 25 ++++++++++++++++- components/lwp/arch/risc-v/rv64/lwp_arch.h | 10 +++---- components/lwp/lwp.c | 37 +++++++++++++++++++++++++ components/lwp/lwp.h | 3 ++ components/lwp/lwp_arch_comm.h | 2 ++ components/lwp/lwp_internal.c | 2 ++ components/lwp/lwp_internal.h | 4 ++- 8 files changed, 100 insertions(+), 8 deletions(-) (limited to 'components') diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c index e46b8ac59a..9f88685610 100644 --- a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c +++ b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c @@ -7,6 +7,7 @@ * Date Author Notes * 2021-05-18 Jesven first version * 2023-07-16 Shell Move part of the codes to C from asm in signal handling + * 2023-10-16 Shell Support a new backtrace framework */ #include @@ -14,7 +15,7 @@ #include #include #include -#include +#include #ifdef ARCH_MM_MMU @@ -161,3 +162,25 @@ void *arch_signal_ucontext_save(rt_base_t user_sp, siginfo_t *psiginfo, return new_sp; } + +int arch_backtrace_uthread(rt_thread_t thread) +{ + struct rt_hw_backtrace_frame frame; + struct rt_hw_exp_stack *stack; + + if (thread && thread->lwp) + { + stack = thread->user_ctx.ctx; + if ((long)stack > (unsigned long)thread->stack_addr + && (long)stack < (unsigned long)thread->stack_addr + thread->stack_size) + { + frame.pc = stack->pc; + frame.fp = stack->x29; + lwp_backtrace_frame(thread, &frame); + return 0; + } + else + return -1; + } + return -1; +} diff --git a/components/lwp/arch/risc-v/rv64/lwp_arch.c b/components/lwp/arch/risc-v/rv64/lwp_arch.c index 387a54f073..4b3dfc2e19 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_arch.c +++ b/components/lwp/arch/risc-v/rv64/lwp_arch.c @@ -15,6 +15,7 @@ * 2021-11-22 JasonHu add lwp_set_thread_context * 2021-11-30 JasonHu add clone/fork support * 2023-07-16 Shell Move part of the codes to C from asm in signal handling + * 2023-10-16 Shell Support a new backtrace framework */ #include #include @@ -27,7 +28,7 @@ #define DBG_LVL DBG_INFO #include -#include +#include #include #include #include @@ -325,3 +326,25 @@ void lwp_exec_user(void *args, void *kernel_stack, void *user_entry) } #endif /* ARCH_MM_MMU */ + +int arch_backtrace_uthread(rt_thread_t thread) +{ + struct rt_hw_backtrace_frame frame; + struct rt_hw_stack_frame *stack; + + if (thread && thread->lwp) + { + stack = thread->user_ctx.ctx; + if ((long)stack > (unsigned long)thread->stack_addr + && (long)stack < (unsigned long)thread->stack_addr + thread->stack_size) + { + frame.pc = stack->epc; + frame.fp = stack->s0_fp; + lwp_backtrace_frame(thread, &frame); + return 0; + } + else + return -1; + } + return -1; +} diff --git a/components/lwp/arch/risc-v/rv64/lwp_arch.h b/components/lwp/arch/risc-v/rv64/lwp_arch.h index 3b78f39355..99f3c62ed9 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_arch.h +++ b/components/lwp/arch/risc-v/rv64/lwp_arch.h @@ -27,13 +27,13 @@ #define LDSO_LOAD_VADDR USER_LOAD_VADDR #else #define USER_HEAP_VADDR 0x300000000UL -#define USER_HEAP_VEND 0xffffffffffff0000UL -#define USER_STACK_VSTART 0x270000000UL -#define USER_STACK_VEND USER_HEAP_VADDR +#define USER_HEAP_VEND USER_STACK_VSTART +#define USER_STACK_VSTART 0x370000000UL +#define USER_STACK_VEND 0x400000000UL #define USER_VADDR_START 0x200000000UL #define USER_VADDR_TOP 0xfffffffffffff000UL -#define USER_LOAD_VADDR 0x200000000 -#define LDSO_LOAD_VADDR 0x200000000 +#define USER_LOAD_VADDR 0x200000000UL +#define LDSO_LOAD_VADDR 0x200000000UL #endif /* this attribution is cpu specified, and it should be defined in riscv_mmu.h */ diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c index 73847fd856..c89a4047c3 100644 --- a/components/lwp/lwp.c +++ b/components/lwp/lwp.c @@ -11,6 +11,7 @@ * 2021-08-26 linzhenxing add lwp_setcwd\lwp_getcwd * 2023-02-20 wangxiaoyao inv icache before new app startup * 2023-02-20 wangxiaoyao fix bug on foreground app switch + * 2023-10-16 Shell Support a new backtrace framework */ #define DBG_TAG "LWP" @@ -1420,6 +1421,42 @@ void lwp_uthread_ctx_restore(void) thread->user_ctx.ctx = RT_NULL; } +rt_err_t lwp_backtrace_frame(rt_thread_t uthread, struct rt_hw_backtrace_frame *frame) +{ + rt_err_t rc = -RT_ERROR; + long nesting = 0; + char **argv; + rt_lwp_t lwp; + + if (uthread->lwp) + { + lwp = uthread->lwp; + argv = lwp_get_command_line_args(lwp); + if (argv) + { + LOG_RAW("please use: addr2line -e %s -a -f", argv[0]); + lwp_free_command_line_args(argv); + } + else + { + LOG_RAW("please use: addr2line -e %s -a -f", lwp->cmd); + } + + while (nesting < RT_BACKTRACE_LEVEL_MAX_NR) + { + LOG_RAW(" 0x%lx", frame->pc); + if (rt_hw_backtrace_frame_unwind(uthread, frame)) + { + break; + } + nesting++; + } + LOG_RAW("\n"); + rc = RT_EOK; + } + return rc; +} + void rt_update_process_times(void) { struct rt_thread *thread; diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 2fcd880bc4..56298a0385 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -321,4 +321,7 @@ void dbg_attach_req(void *pc); int dbg_check_suspend(void); void rt_hw_set_process_id(int pid); +/* backtrace service */ +rt_err_t lwp_backtrace_frame(rt_thread_t uthread, struct rt_hw_backtrace_frame *frame); + #endif diff --git a/components/lwp/lwp_arch_comm.h b/components/lwp/lwp_arch_comm.h index bfd91ec189..b7cb5c2347 100644 --- a/components/lwp/lwp_arch_comm.h +++ b/components/lwp/lwp_arch_comm.h @@ -61,4 +61,6 @@ rt_noreturn void arch_thread_signal_enter(int signo, siginfo_t *psiginfo, void *exp_frame, void *entry_uaddr, lwp_sigset_t *save_sig_mask); +int arch_backtrace_uthread(rt_thread_t thread); + #endif /* __LWP_ARCH_COMM__ */ diff --git a/components/lwp/lwp_internal.c b/components/lwp/lwp_internal.c index 44f56ea95f..21ca4e6e14 100644 --- a/components/lwp/lwp_internal.c +++ b/components/lwp/lwp_internal.c @@ -56,6 +56,7 @@ static rt_err_t _mutex_take_safe(rt_mutex_t mtx, rt_int32_t timeout, rt_bool_t i if (rt_mutex_get_hold(mtx) > 1) { LOG_W("Already hold the lock"); + rt_backtrace(); } } else if (rc == -RT_ETIMEOUT) @@ -109,6 +110,7 @@ rt_err_t lwp_mutex_release_safe(rt_mutex_t mtx) if (rc) { LOG_I("%s: release failed with code %ld", __func__, rc); + rt_backtrace(); } RETURN(rc); diff --git a/components/lwp/lwp_internal.h b/components/lwp/lwp_internal.h index 703bf7c0ae..f461b7fa26 100644 --- a/components/lwp/lwp_internal.h +++ b/components/lwp/lwp_internal.h @@ -11,8 +11,10 @@ #ifndef __LWP_INTERNAL_H__ #define __LWP_INTERNAL_H__ -#include #include "lwp.h" +#include "lwp_user_mm.h" + +#include #include "libc_musl.h" struct rt_lwp; -- cgit v1.3.1