Skip to content

Commit 4d7bf93

Browse files
zhangqingmychenhuacai
authored andcommitted
LoongArch: Add USER_STACKTRACE support
To get the best stacktrace output, you can compile your userspace programs with frame pointers (at least glibc + the app you are tracing). 1, export "CC = gcc -fno-omit-frame-pointer"; 2, compile your programs with "CC"; 3, use uprobe to get stacktrace output. ... 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> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 93a4fa6 commit 4d7bf93

3 files changed

Lines changed: 47 additions & 0 deletions

File tree

arch/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ config LOONGARCH
119119
select SWIOTLB
120120
select TRACE_IRQFLAGS_SUPPORT
121121
select USE_PERCPU_NUMA_NODE_ID
122+
select USER_STACKTRACE_SUPPORT
122123
select ZONE_DMA32
123124

124125
config 32BIT

arch/loongarch/include/asm/stacktrace.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ struct stack_info {
2121
unsigned long begin, end, next_sp;
2222
};
2323

24+
struct stack_frame {
25+
unsigned long fp;
26+
unsigned long ra;
27+
};
28+
2429
bool in_irq_stack(unsigned long stack, struct stack_info *info);
2530
bool in_task_stack(unsigned long stack, struct task_struct *task, struct stack_info *info);
2631
int get_stack_info(unsigned long stack, struct task_struct *task, struct stack_info *info);

arch/loongarch/kernel/stacktrace.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
#include <linux/sched.h>
88
#include <linux/stacktrace.h>
9+
#include <linux/uaccess.h>
910

1011
#include <asm/stacktrace.h>
1112
#include <asm/unwind.h>
@@ -35,3 +36,43 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
3536
break;
3637
}
3738
}
39+
40+
static int
41+
copy_stack_frame(unsigned long fp, struct stack_frame *frame)
42+
{
43+
int ret = 1;
44+
unsigned long err;
45+
unsigned long __user *user_frame_tail;
46+
47+
user_frame_tail = (unsigned long *)(fp - sizeof(struct stack_frame));
48+
if (!access_ok(user_frame_tail, sizeof(*frame)))
49+
return 0;
50+
51+
pagefault_disable();
52+
err = (__copy_from_user_inatomic(frame, user_frame_tail, sizeof(*frame)));
53+
if (err || (unsigned long)user_frame_tail >= frame->fp)
54+
ret = 0;
55+
pagefault_enable();
56+
57+
return ret;
58+
}
59+
60+
void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
61+
const struct pt_regs *regs)
62+
{
63+
unsigned long fp = regs->regs[22];
64+
65+
while (fp && !((unsigned long)fp & 0xf)) {
66+
struct stack_frame frame;
67+
68+
frame.fp = 0;
69+
frame.ra = 0;
70+
if (!copy_stack_frame(fp, &frame))
71+
break;
72+
if (!frame.ra)
73+
break;
74+
if (!consume_entry(cookie, frame.ra))
75+
break;
76+
fp = frame.fp;
77+
}
78+
}

0 commit comments

Comments
 (0)