linux/kernel/debug/kdb/kdb_bt.c
<<
>>
Prefs
   1/*
   2 * Kernel Debugger Architecture Independent Stack Traceback
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.  See the file "COPYING" in the main directory of this archive
   6 * for more details.
   7 *
   8 * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
   9 * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
  10 */
  11
  12#include <linux/ctype.h>
  13#include <linux/string.h>
  14#include <linux/kernel.h>
  15#include <linux/sched.h>
  16#include <linux/kdb.h>
  17#include <linux/nmi.h>
  18#include "kdb_private.h"
  19
  20
  21static void kdb_show_stack(struct task_struct *p, void *addr)
  22{
  23        int old_lvl = console_loglevel;
  24        console_loglevel = 15;
  25        kdb_trap_printk++;
  26        kdb_set_current_task(p);
  27        if (addr) {
  28                show_stack((struct task_struct *)p, addr);
  29        } else if (kdb_current_regs) {
  30#ifdef CONFIG_X86
  31                show_stack(p, &kdb_current_regs->sp);
  32#else
  33                show_stack(p, NULL);
  34#endif
  35        } else {
  36                show_stack(p, NULL);
  37        }
  38        console_loglevel = old_lvl;
  39        kdb_trap_printk--;
  40}
  41
  42/*
  43 * kdb_bt
  44 *
  45 *      This function implements the 'bt' command.  Print a stack
  46 *      traceback.
  47 *
  48 *      bt [<address-expression>]       (addr-exp is for alternate stacks)
  49 *      btp <pid>                       Kernel stack for <pid>
  50 *      btt <address-expression>        Kernel stack for task structure at
  51 *                                      <address-expression>
  52 *      bta [DRSTCZEUIMA]               All useful processes, optionally
  53 *                                      filtered by state
  54 *      btc [<cpu>]                     The current process on one cpu,
  55 *                                      default is all cpus
  56 *
  57 *      bt <address-expression> refers to a address on the stack, that location
  58 *      is assumed to contain a return address.
  59 *
  60 *      btt <address-expression> refers to the address of a struct task.
  61 *
  62 * Inputs:
  63 *      argc    argument count
  64 *      argv    argument vector
  65 * Outputs:
  66 *      None.
  67 * Returns:
  68 *      zero for success, a kdb diagnostic if error
  69 * Locking:
  70 *      none.
  71 * Remarks:
  72 *      Backtrack works best when the code uses frame pointers.  But even
  73 *      without frame pointers we should get a reasonable trace.
  74 *
  75 *      mds comes in handy when examining the stack to do a manual traceback or
  76 *      to get a starting point for bt <address-expression>.
  77 */
  78
  79static int
  80kdb_bt1(struct task_struct *p, unsigned long mask,
  81        int argcount, int btaprompt)
  82{
  83        char buffer[2];
  84        if (kdb_getarea(buffer[0], (unsigned long)p) ||
  85            kdb_getarea(buffer[0], (unsigned long)(p+1)-1))
  86                return KDB_BADADDR;
  87        if (!kdb_task_state(p, mask))
  88                return 0;
  89        kdb_printf("Stack traceback for pid %d\n", p->pid);
  90        kdb_ps1(p);
  91        kdb_show_stack(p, NULL);
  92        if (btaprompt) {
  93                kdb_getstr(buffer, sizeof(buffer),
  94                           "Enter <q> to end, <cr> to continue:");
  95                if (buffer[0] == 'q') {
  96                        kdb_printf("\n");
  97                        return 1;
  98                }
  99        }
 100        touch_nmi_watchdog();
 101        return 0;
 102}
 103
 104int
 105kdb_bt(int argc, const char **argv)
 106{
 107        int diag;
 108        int argcount = 5;
 109        int btaprompt = 1;
 110        int nextarg;
 111        unsigned long addr;
 112        long offset;
 113
 114        /* Prompt after each proc in bta */
 115        kdbgetintenv("BTAPROMPT", &btaprompt);
 116
 117        if (strcmp(argv[0], "bta") == 0) {
 118                struct task_struct *g, *p;
 119                unsigned long cpu;
 120                unsigned long mask = kdb_task_state_string(argc ? argv[1] :
 121                                                           NULL);
 122                if (argc == 0)
 123                        kdb_ps_suppressed();
 124                /* Run the active tasks first */
 125                for_each_online_cpu(cpu) {
 126                        p = kdb_curr_task(cpu);
 127                        if (kdb_bt1(p, mask, argcount, btaprompt))
 128                                return 0;
 129                }
 130                /* Now the inactive tasks */
 131                kdb_do_each_thread(g, p) {
 132                        if (KDB_FLAG(CMD_INTERRUPT))
 133                                return 0;
 134                        if (task_curr(p))
 135                                continue;
 136                        if (kdb_bt1(p, mask, argcount, btaprompt))
 137                                return 0;
 138                } kdb_while_each_thread(g, p);
 139        } else if (strcmp(argv[0], "btp") == 0) {
 140                struct task_struct *p;
 141                unsigned long pid;
 142                if (argc != 1)
 143                        return KDB_ARGCOUNT;
 144                diag = kdbgetularg((char *)argv[1], &pid);
 145                if (diag)
 146                        return diag;
 147                p = find_task_by_pid_ns(pid, &init_pid_ns);
 148                if (p) {
 149                        kdb_set_current_task(p);
 150                        return kdb_bt1(p, ~0UL, argcount, 0);
 151                }
 152                kdb_printf("No process with pid == %ld found\n", pid);
 153                return 0;
 154        } else if (strcmp(argv[0], "btt") == 0) {
 155                if (argc != 1)
 156                        return KDB_ARGCOUNT;
 157                diag = kdbgetularg((char *)argv[1], &addr);
 158                if (diag)
 159                        return diag;
 160                kdb_set_current_task((struct task_struct *)addr);
 161                return kdb_bt1((struct task_struct *)addr, ~0UL, argcount, 0);
 162        } else if (strcmp(argv[0], "btc") == 0) {
 163                unsigned long cpu = ~0;
 164                struct task_struct *save_current_task = kdb_current_task;
 165                char buf[80];
 166                if (argc > 1)
 167                        return KDB_ARGCOUNT;
 168                if (argc == 1) {
 169                        diag = kdbgetularg((char *)argv[1], &cpu);
 170                        if (diag)
 171                                return diag;
 172                }
 173                /* Recursive use of kdb_parse, do not use argv after
 174                 * this point */
 175                argv = NULL;
 176                if (cpu != ~0) {
 177                        if (cpu >= num_possible_cpus() || !cpu_online(cpu)) {
 178                                kdb_printf("no process for cpu %ld\n", cpu);
 179                                return 0;
 180                        }
 181                        sprintf(buf, "btt 0x%p\n", KDB_TSK(cpu));
 182                        kdb_parse(buf);
 183                        return 0;
 184                }
 185                kdb_printf("btc: cpu status: ");
 186                kdb_parse("cpu\n");
 187                for_each_online_cpu(cpu) {
 188                        sprintf(buf, "btt 0x%p\n", KDB_TSK(cpu));
 189                        kdb_parse(buf);
 190                        touch_nmi_watchdog();
 191                }
 192                kdb_set_current_task(save_current_task);
 193                return 0;
 194        } else {
 195                if (argc) {
 196                        nextarg = 1;
 197                        diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
 198                                             &offset, NULL);
 199                        if (diag)
 200                                return diag;
 201                        kdb_show_stack(kdb_current_task, (void *)addr);
 202                        return 0;
 203                } else {
 204                        return kdb_bt1(kdb_current_task, ~0UL, argcount, 0);
 205                }
 206        }
 207
 208        /* NOTREACHED */
 209        return 0;
 210}
 211