Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * kernel/stacktrace.c
4 : : *
5 : : * Stack trace management functions
6 : : *
7 : : * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
8 : : */
9 : : #include <linux/sched/task_stack.h>
10 : : #include <linux/sched/debug.h>
11 : : #include <linux/sched.h>
12 : : #include <linux/kernel.h>
13 : : #include <linux/export.h>
14 : : #include <linux/kallsyms.h>
15 : : #include <linux/stacktrace.h>
16 : :
17 : : /**
18 : : * stack_trace_print - Print the entries in the stack trace
19 : : * @entries: Pointer to storage array
20 : : * @nr_entries: Number of entries in the storage array
21 : : * @spaces: Number of leading spaces to print
22 : : */
23 : 0 : void stack_trace_print(const unsigned long *entries, unsigned int nr_entries,
24 : : int spaces)
25 : : {
26 : : unsigned int i;
27 : :
28 [ # # # # ]: 0 : if (WARN_ON(!entries))
29 : 0 : return;
30 : :
31 [ # # ]: 0 : for (i = 0; i < nr_entries; i++)
32 : 0 : printk("%*c%pS\n", 1 + spaces, ' ', (void *)entries[i]);
33 : : }
34 : : EXPORT_SYMBOL_GPL(stack_trace_print);
35 : :
36 : : /**
37 : : * stack_trace_snprint - Print the entries in the stack trace into a buffer
38 : : * @buf: Pointer to the print buffer
39 : : * @size: Size of the print buffer
40 : : * @entries: Pointer to storage array
41 : : * @nr_entries: Number of entries in the storage array
42 : : * @spaces: Number of leading spaces to print
43 : : *
44 : : * Return: Number of bytes printed.
45 : : */
46 : 0 : int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries,
47 : : unsigned int nr_entries, int spaces)
48 : : {
49 : : unsigned int generated, i, total = 0;
50 : :
51 [ # # # # ]: 0 : if (WARN_ON(!entries))
52 : : return 0;
53 : :
54 [ # # ]: 0 : for (i = 0; i < nr_entries && size; i++) {
55 : 0 : generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
56 : 0 : (void *)entries[i]);
57 : :
58 : 0 : total += generated;
59 [ # # ]: 0 : if (generated >= size) {
60 : 0 : buf += size;
61 : : size = 0;
62 : : } else {
63 : 0 : buf += generated;
64 : 0 : size -= generated;
65 : : }
66 : : }
67 : :
68 : 0 : return total;
69 : : }
70 : : EXPORT_SYMBOL_GPL(stack_trace_snprint);
71 : :
72 : : #ifdef CONFIG_ARCH_STACKWALK
73 : :
74 : : struct stacktrace_cookie {
75 : : unsigned long *store;
76 : : unsigned int size;
77 : : unsigned int skip;
78 : : unsigned int len;
79 : : };
80 : :
81 : : static bool stack_trace_consume_entry(void *cookie, unsigned long addr,
82 : : bool reliable)
83 : : {
84 : : struct stacktrace_cookie *c = cookie;
85 : :
86 : : if (c->len >= c->size)
87 : : return false;
88 : :
89 : : if (c->skip > 0) {
90 : : c->skip--;
91 : : return true;
92 : : }
93 : : c->store[c->len++] = addr;
94 : : return c->len < c->size;
95 : : }
96 : :
97 : : static bool stack_trace_consume_entry_nosched(void *cookie, unsigned long addr,
98 : : bool reliable)
99 : : {
100 : : if (in_sched_functions(addr))
101 : : return true;
102 : : return stack_trace_consume_entry(cookie, addr, reliable);
103 : : }
104 : :
105 : : /**
106 : : * stack_trace_save - Save a stack trace into a storage array
107 : : * @store: Pointer to storage array
108 : : * @size: Size of the storage array
109 : : * @skipnr: Number of entries to skip at the start of the stack trace
110 : : *
111 : : * Return: Number of trace entries stored.
112 : : */
113 : : unsigned int stack_trace_save(unsigned long *store, unsigned int size,
114 : : unsigned int skipnr)
115 : : {
116 : : stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
117 : : struct stacktrace_cookie c = {
118 : : .store = store,
119 : : .size = size,
120 : : .skip = skipnr + 1,
121 : : };
122 : :
123 : : arch_stack_walk(consume_entry, &c, current, NULL);
124 : : return c.len;
125 : : }
126 : : EXPORT_SYMBOL_GPL(stack_trace_save);
127 : :
128 : : /**
129 : : * stack_trace_save_tsk - Save a task stack trace into a storage array
130 : : * @task: The task to examine
131 : : * @store: Pointer to storage array
132 : : * @size: Size of the storage array
133 : : * @skipnr: Number of entries to skip at the start of the stack trace
134 : : *
135 : : * Return: Number of trace entries stored.
136 : : */
137 : : unsigned int stack_trace_save_tsk(struct task_struct *tsk, unsigned long *store,
138 : : unsigned int size, unsigned int skipnr)
139 : : {
140 : : stack_trace_consume_fn consume_entry = stack_trace_consume_entry_nosched;
141 : : struct stacktrace_cookie c = {
142 : : .store = store,
143 : : .size = size,
144 : : /* skip this function if they are tracing us */
145 : : .skip = skipnr + !!(current == tsk),
146 : : };
147 : :
148 : : if (!try_get_task_stack(tsk))
149 : : return 0;
150 : :
151 : : arch_stack_walk(consume_entry, &c, tsk, NULL);
152 : : put_task_stack(tsk);
153 : : return c.len;
154 : : }
155 : :
156 : : /**
157 : : * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
158 : : * @regs: Pointer to pt_regs to examine
159 : : * @store: Pointer to storage array
160 : : * @size: Size of the storage array
161 : : * @skipnr: Number of entries to skip at the start of the stack trace
162 : : *
163 : : * Return: Number of trace entries stored.
164 : : */
165 : : unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
166 : : unsigned int size, unsigned int skipnr)
167 : : {
168 : : stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
169 : : struct stacktrace_cookie c = {
170 : : .store = store,
171 : : .size = size,
172 : : .skip = skipnr,
173 : : };
174 : :
175 : : arch_stack_walk(consume_entry, &c, current, regs);
176 : : return c.len;
177 : : }
178 : :
179 : : #ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
180 : : /**
181 : : * stack_trace_save_tsk_reliable - Save task stack with verification
182 : : * @tsk: Pointer to the task to examine
183 : : * @store: Pointer to storage array
184 : : * @size: Size of the storage array
185 : : *
186 : : * Return: An error if it detects any unreliable features of the
187 : : * stack. Otherwise it guarantees that the stack trace is
188 : : * reliable and returns the number of entries stored.
189 : : *
190 : : * If the task is not 'current', the caller *must* ensure the task is inactive.
191 : : */
192 : : int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
193 : : unsigned int size)
194 : : {
195 : : stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
196 : : struct stacktrace_cookie c = {
197 : : .store = store,
198 : : .size = size,
199 : : };
200 : : int ret;
201 : :
202 : : /*
203 : : * If the task doesn't have a stack (e.g., a zombie), the stack is
204 : : * "reliably" empty.
205 : : */
206 : : if (!try_get_task_stack(tsk))
207 : : return 0;
208 : :
209 : : ret = arch_stack_walk_reliable(consume_entry, &c, tsk);
210 : : put_task_stack(tsk);
211 : : return ret ? ret : c.len;
212 : : }
213 : : #endif
214 : :
215 : : #ifdef CONFIG_USER_STACKTRACE_SUPPORT
216 : : /**
217 : : * stack_trace_save_user - Save a user space stack trace into a storage array
218 : : * @store: Pointer to storage array
219 : : * @size: Size of the storage array
220 : : *
221 : : * Return: Number of trace entries stored.
222 : : */
223 : : unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
224 : : {
225 : : stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
226 : : struct stacktrace_cookie c = {
227 : : .store = store,
228 : : .size = size,
229 : : };
230 : : mm_segment_t fs;
231 : :
232 : : /* Trace user stack if not a kernel thread */
233 : : if (current->flags & PF_KTHREAD)
234 : : return 0;
235 : :
236 : : fs = get_fs();
237 : : set_fs(USER_DS);
238 : : arch_stack_walk_user(consume_entry, &c, task_pt_regs(current));
239 : : set_fs(fs);
240 : :
241 : : return c.len;
242 : : }
243 : : #endif
244 : :
245 : : #else /* CONFIG_ARCH_STACKWALK */
246 : :
247 : : /*
248 : : * Architectures that do not implement save_stack_trace_*()
249 : : * get these weak aliases and once-per-bootup warnings
250 : : * (whenever this facility is utilized - for example by procfs):
251 : : */
252 : : __weak void
253 : 0 : save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
254 : : {
255 [ # # ]: 0 : WARN_ONCE(1, KERN_INFO "save_stack_trace_tsk() not implemented yet.\n");
256 : 0 : }
257 : :
258 : : __weak void
259 : 0 : save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
260 : : {
261 [ # # ]: 0 : WARN_ONCE(1, KERN_INFO "save_stack_trace_regs() not implemented yet.\n");
262 : 0 : }
263 : :
264 : : /**
265 : : * stack_trace_save - Save a stack trace into a storage array
266 : : * @store: Pointer to storage array
267 : : * @size: Size of the storage array
268 : : * @skipnr: Number of entries to skip at the start of the stack trace
269 : : *
270 : : * Return: Number of trace entries stored
271 : : */
272 : 0 : unsigned int stack_trace_save(unsigned long *store, unsigned int size,
273 : : unsigned int skipnr)
274 : : {
275 : 0 : struct stack_trace trace = {
276 : : .entries = store,
277 : : .max_entries = size,
278 : 0 : .skip = skipnr + 1,
279 : : };
280 : :
281 : 0 : save_stack_trace(&trace);
282 : 0 : return trace.nr_entries;
283 : : }
284 : : EXPORT_SYMBOL_GPL(stack_trace_save);
285 : :
286 : : /**
287 : : * stack_trace_save_tsk - Save a task stack trace into a storage array
288 : : * @task: The task to examine
289 : : * @store: Pointer to storage array
290 : : * @size: Size of the storage array
291 : : * @skipnr: Number of entries to skip at the start of the stack trace
292 : : *
293 : : * Return: Number of trace entries stored
294 : : */
295 : 0 : unsigned int stack_trace_save_tsk(struct task_struct *task,
296 : : unsigned long *store, unsigned int size,
297 : : unsigned int skipnr)
298 : : {
299 : 0 : struct stack_trace trace = {
300 : : .entries = store,
301 : : .max_entries = size,
302 : : /* skip this function if they are tracing us */
303 : 0 : .skip = skipnr + !!(current == task),
304 : : };
305 : :
306 : 0 : save_stack_trace_tsk(task, &trace);
307 : 0 : return trace.nr_entries;
308 : : }
309 : :
310 : : /**
311 : : * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
312 : : * @regs: Pointer to pt_regs to examine
313 : : * @store: Pointer to storage array
314 : : * @size: Size of the storage array
315 : : * @skipnr: Number of entries to skip at the start of the stack trace
316 : : *
317 : : * Return: Number of trace entries stored
318 : : */
319 : 0 : unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
320 : : unsigned int size, unsigned int skipnr)
321 : : {
322 : 0 : struct stack_trace trace = {
323 : : .entries = store,
324 : : .max_entries = size,
325 : : .skip = skipnr,
326 : : };
327 : :
328 : 0 : save_stack_trace_regs(regs, &trace);
329 : 0 : return trace.nr_entries;
330 : : }
331 : :
332 : : #ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
333 : : /**
334 : : * stack_trace_save_tsk_reliable - Save task stack with verification
335 : : * @tsk: Pointer to the task to examine
336 : : * @store: Pointer to storage array
337 : : * @size: Size of the storage array
338 : : *
339 : : * Return: An error if it detects any unreliable features of the
340 : : * stack. Otherwise it guarantees that the stack trace is
341 : : * reliable and returns the number of entries stored.
342 : : *
343 : : * If the task is not 'current', the caller *must* ensure the task is inactive.
344 : : */
345 : : int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
346 : : unsigned int size)
347 : : {
348 : : struct stack_trace trace = {
349 : : .entries = store,
350 : : .max_entries = size,
351 : : };
352 : : int ret = save_stack_trace_tsk_reliable(tsk, &trace);
353 : :
354 : : return ret ? ret : trace.nr_entries;
355 : : }
356 : : #endif
357 : :
358 : : #ifdef CONFIG_USER_STACKTRACE_SUPPORT
359 : : /**
360 : : * stack_trace_save_user - Save a user space stack trace into a storage array
361 : : * @store: Pointer to storage array
362 : : * @size: Size of the storage array
363 : : *
364 : : * Return: Number of trace entries stored
365 : : */
366 : : unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
367 : : {
368 : : struct stack_trace trace = {
369 : : .entries = store,
370 : : .max_entries = size,
371 : : };
372 : :
373 : : save_stack_trace_user(&trace);
374 : : return trace.nr_entries;
375 : : }
376 : : #endif /* CONFIG_USER_STACKTRACE_SUPPORT */
377 : :
378 : : #endif /* !CONFIG_ARCH_STACKWALK */
|