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