1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
5 * Copyright (C) 2009 Matt Fleming
6 * Copyright (C) 2002 - 2012 Paul Mundt
8 #include <linux/kallsyms.h>
9 #include <linux/ftrace.h>
10 #include <linux/debug_locks.h>
11 #include <linux/sched/debug.h>
12 #include <linux/sched/task_stack.h>
13 #include <linux/kdebug.h>
14 #include <linux/export.h>
15 #include <linux/uaccess.h>
16 #include <asm/unwinder.h>
17 #include <asm/stacktrace.h>
19 void dump_mem(const char *str
, const char *loglvl
, unsigned long bottom
,
25 printk("%s%s(0x%08lx to 0x%08lx)\n", loglvl
, str
, bottom
, top
);
27 for (p
= bottom
& ~31; p
< top
; ) {
28 printk("%s%04lx: ", loglvl
, p
& 0xffff);
30 for (i
= 0; i
< 8; i
++, p
+= 4) {
33 if (p
< bottom
|| p
>= top
)
36 if (__get_user(val
, (unsigned int __user
*)p
)) {
40 pr_cont("%08x ", val
);
47 void printk_address(unsigned long address
, int reliable
)
49 pr_cont(" [<%px>] %s%pS\n", (void *) address
,
50 reliable
? "" : "? ", (void *) address
);
53 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
55 print_ftrace_graph_addr(unsigned long addr
, void *data
,
56 const struct stacktrace_ops
*ops
,
57 struct thread_info
*tinfo
, int *graph
)
59 struct task_struct
*task
= tinfo
->task
;
60 struct ftrace_ret_stack
*ret_stack
;
61 unsigned long ret_addr
;
63 if (addr
!= (unsigned long)return_to_handler
)
69 ret_stack
= ftrace_graph_get_ret_stack(task
, *graph
);
73 ret_addr
= ret_stack
->ret
;
75 ops
->address(data
, ret_addr
, 1);
81 print_ftrace_graph_addr(unsigned long addr
, void *data
,
82 const struct stacktrace_ops
*ops
,
83 struct thread_info
*tinfo
, int *graph
)
88 stack_reader_dump(struct task_struct
*task
, struct pt_regs
*regs
,
89 unsigned long *sp
, const struct stacktrace_ops
*ops
,
92 struct thread_info
*context
;
95 context
= (struct thread_info
*)
96 ((unsigned long)sp
& (~(THREAD_SIZE
- 1)));
98 while (!kstack_end(sp
)) {
99 unsigned long addr
= *sp
++;
101 if (__kernel_text_address(addr
)) {
102 ops
->address(data
, addr
, 1);
104 print_ftrace_graph_addr(addr
, data
, ops
,
111 * Print one address/symbol entries per line.
113 static void print_trace_address(void *data
, unsigned long addr
, int reliable
)
115 printk("%s", (char *)data
);
116 printk_address(addr
, reliable
);
119 static const struct stacktrace_ops print_trace_ops
= {
120 .address
= print_trace_address
,
123 void show_trace(struct task_struct
*tsk
, unsigned long *sp
,
124 struct pt_regs
*regs
, const char *loglvl
)
126 if (regs
&& user_mode(regs
))
129 printk("%s\nCall trace:\n", loglvl
);
131 unwind_stack(tsk
, regs
, sp
, &print_trace_ops
, (void *)loglvl
);
138 debug_show_held_locks(tsk
);
141 void show_stack(struct task_struct
*tsk
, unsigned long *sp
, const char *loglvl
)
148 sp
= (unsigned long *)current_stack_pointer
;
150 sp
= (unsigned long *)tsk
->thread
.sp
;
152 stack
= (unsigned long)sp
;
153 dump_mem("Stack: ", loglvl
, stack
, THREAD_SIZE
+
154 (unsigned long)task_stack_page(tsk
));
155 show_trace(tsk
, sp
, NULL
, loglvl
);