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 */