Messages in this thread | | | From | Huacai Chen <> | Date | Mon, 1 Aug 2022 23:31:30 +0800 | Subject | Re: [PATCH 4/4] LoongArch: Add USER_STACKTRACE support |
| |
Hi, Qing,
On Mon, Aug 1, 2022 at 8:17 PM Qing Zhang <zhangqing@loongson.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@loongson.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 > >
| |