[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAAhV-H4qSbaS3=JJXk4fLMnVp2L_ZbFkrddzad0J3ewZDuGMMg@mail.gmail.com>
Date: Mon, 1 Aug 2022 23:31:30 +0800
From: Huacai Chen <chenhuacai@...nel.org>
To: Qing Zhang <zhangqing@...ngson.cn>
Cc: WANG Xuerui <kernel@...0n.name>, loongarch@...ts.linux.dev,
LKML <linux-kernel@...r.kernel.org>,
Jiaxun Yang <jiaxun.yang@...goat.com>,
Jinyang He <hejinyang@...ngson.cn>
Subject: Re: [PATCH 4/4] LoongArch: Add USER_STACKTRACE support
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@...ngson.cn> wrote:
>
> To get the best output you can compile your userspace programs with
> frame pointers (at least glibc + the app you are tracing export "CC
> =gcc -fno-omit-frame-pointer".
>
> ...
> echo 'p:malloc /usr/lib64/libc.so.6:0x0a4704 size=%r4:u64'
> > uprobe_events
> echo 'p:free /usr/lib64/libc.so.6:0x0a4d50 ptr=%r4:x64'
> >> uprobe_events
> echo 'comm == "demo"' > ./events/uprobes/malloc/filter
> echo 'comm == "demo"' > ./events/uprobes/free/filter
> echo 1 > ./options/userstacktrace
> echo 1 > ./options/sym-userobj
> ...
>
> Signed-off-by: Qing Zhang <zhangqing@...ngson.cn>
> ---
> arch/loongarch/Kconfig | 1 +
> arch/loongarch/include/asm/stacktrace.h | 5 +++
> arch/loongarch/kernel/stacktrace.c | 42 +++++++++++++++++++++++++
> 3 files changed, 48 insertions(+)
>
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 85d0fa3147cd..05906384d564 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -107,6 +107,7 @@ config LOONGARCH
> select SWIOTLB
> select TRACE_IRQFLAGS_SUPPORT
> select USE_PERCPU_NUMA_NODE_ID
> + select USER_STACKTRACE_SUPPORT
> select ZONE_DMA32
> select MMU_GATHER_MERGE_VMAS if MMU
>
> diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
> index 49cb89213aeb..77fdb8ad662d 100644
> --- a/arch/loongarch/include/asm/stacktrace.h
> +++ b/arch/loongarch/include/asm/stacktrace.h
> @@ -21,6 +21,11 @@ struct stack_info {
> unsigned long begin, end, next_sp;
> };
>
> +struct stack_frame {
> + unsigned long fp;
> + unsigned long ra;
> +};
> +
> bool in_task_stack(unsigned long stack, struct task_struct *task,
> struct stack_info *info);
> bool in_irq_stack(unsigned long stack, struct stack_info *info);
> diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
> index f4f4b8ad3917..344224c7cb0e 100644
> --- a/arch/loongarch/kernel/stacktrace.c
> +++ b/arch/loongarch/kernel/stacktrace.c
> @@ -6,6 +6,7 @@
> */
> #include <linux/sched.h>
> #include <linux/stacktrace.h>
> +#include <linux/uaccess.h>
>
> #include <asm/stacktrace.h>
> #include <asm/unwind.h>
> @@ -35,3 +36,44 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
> break;
> }
> }
> +
> +static int
> +copy_stack_frame(unsigned long fp, struct stack_frame *frame)
> +{
> + int ret;
> + unsigned long err;
> + unsigned long __user *user_frame_tail;
> +
> + user_frame_tail = (unsigned long *)(fp - sizeof(struct stack_frame));
> + if (!access_ok(user_frame_tail, sizeof(*frame)))
> + return 0;
> +
> + ret = 1;
Maybe initializing it at its definition is better?
Huacai
> + pagefault_disable();
> + err = (__copy_from_user_inatomic(frame, user_frame_tail, sizeof(*frame)));
> + if (err || (unsigned long)user_frame_tail >= frame->fp)
> + ret = 0;
> + pagefault_enable();
> +
> + return ret;
> +}
> +
> +void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
> + const struct pt_regs *regs)
> +{
> + unsigned long fp = regs->regs[22];
> +
> + while (fp && !((unsigned long)fp & 0xf)) {
> + struct stack_frame frame;
> +
> + frame.fp = 0;
> + frame.ra = 0;
> + if (!copy_stack_frame(fp, &frame))
> + break;
> + if (!frame.ra)
> + break;
> + if (!consume_entry(cookie, frame.ra))
> + break;
> + fp = frame.fp;
> + }
> +}
> --
> 2.20.1
>
>
Powered by blists - more mailing lists