0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/ctype.h>
0013 #include <linux/string.h>
0014 #include <linux/kernel.h>
0015 #include <linux/sched/signal.h>
0016 #include <linux/sched/debug.h>
0017 #include <linux/kdb.h>
0018 #include <linux/nmi.h>
0019 #include "kdb_private.h"
0020
0021
0022 static void kdb_show_stack(struct task_struct *p, void *addr)
0023 {
0024 kdb_trap_printk++;
0025
0026 if (!addr && kdb_task_has_cpu(p)) {
0027 int old_lvl = console_loglevel;
0028
0029 console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
0030 kdb_dump_stack_on_cpu(kdb_process_cpu(p));
0031 console_loglevel = old_lvl;
0032 } else {
0033 show_stack(p, addr, KERN_EMERG);
0034 }
0035
0036 kdb_trap_printk--;
0037 }
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static int
0077 kdb_bt1(struct task_struct *p, const char *mask, bool btaprompt)
0078 {
0079 char ch;
0080
0081 if (kdb_getarea(ch, (unsigned long)p) ||
0082 kdb_getarea(ch, (unsigned long)(p+1)-1))
0083 return KDB_BADADDR;
0084 if (!kdb_task_state(p, mask))
0085 return 0;
0086 kdb_printf("Stack traceback for pid %d\n", p->pid);
0087 kdb_ps1(p);
0088 kdb_show_stack(p, NULL);
0089 if (btaprompt) {
0090 kdb_printf("Enter <q> to end, <cr> or <space> to continue:");
0091 do {
0092 ch = kdb_getchar();
0093 } while (!strchr("\r\n q", ch));
0094 kdb_printf("\n");
0095
0096
0097 kdb_nextline = 1;
0098
0099 if (ch == 'q')
0100 return 1;
0101 }
0102 touch_nmi_watchdog();
0103 return 0;
0104 }
0105
0106 static void
0107 kdb_bt_cpu(unsigned long cpu)
0108 {
0109 struct task_struct *kdb_tsk;
0110
0111 if (cpu >= num_possible_cpus() || !cpu_online(cpu)) {
0112 kdb_printf("WARNING: no process for cpu %ld\n", cpu);
0113 return;
0114 }
0115
0116
0117 kdb_tsk = KDB_TSK(cpu);
0118 if (!kdb_tsk) {
0119 kdb_printf("WARNING: no task for cpu %ld\n", cpu);
0120 return;
0121 }
0122
0123 kdb_bt1(kdb_tsk, "A", false);
0124 }
0125
0126 int
0127 kdb_bt(int argc, const char **argv)
0128 {
0129 int diag;
0130 int btaprompt = 1;
0131 int nextarg;
0132 unsigned long addr;
0133 long offset;
0134
0135
0136 kdbgetintenv("BTAPROMPT", &btaprompt);
0137
0138 if (strcmp(argv[0], "bta") == 0) {
0139 struct task_struct *g, *p;
0140 unsigned long cpu;
0141 const char *mask = argc ? argv[1] : kdbgetenv("PS");
0142
0143 if (argc == 0)
0144 kdb_ps_suppressed();
0145
0146 for_each_online_cpu(cpu) {
0147 p = kdb_curr_task(cpu);
0148 if (kdb_bt1(p, mask, btaprompt))
0149 return 0;
0150 }
0151
0152 for_each_process_thread(g, p) {
0153 if (KDB_FLAG(CMD_INTERRUPT))
0154 return 0;
0155 if (task_curr(p))
0156 continue;
0157 if (kdb_bt1(p, mask, btaprompt))
0158 return 0;
0159 }
0160 } else if (strcmp(argv[0], "btp") == 0) {
0161 struct task_struct *p;
0162 unsigned long pid;
0163 if (argc != 1)
0164 return KDB_ARGCOUNT;
0165 diag = kdbgetularg((char *)argv[1], &pid);
0166 if (diag)
0167 return diag;
0168 p = find_task_by_pid_ns(pid, &init_pid_ns);
0169 if (p)
0170 return kdb_bt1(p, "A", false);
0171 kdb_printf("No process with pid == %ld found\n", pid);
0172 return 0;
0173 } else if (strcmp(argv[0], "btt") == 0) {
0174 if (argc != 1)
0175 return KDB_ARGCOUNT;
0176 diag = kdbgetularg((char *)argv[1], &addr);
0177 if (diag)
0178 return diag;
0179 return kdb_bt1((struct task_struct *)addr, "A", false);
0180 } else if (strcmp(argv[0], "btc") == 0) {
0181 unsigned long cpu = ~0;
0182 if (argc > 1)
0183 return KDB_ARGCOUNT;
0184 if (argc == 1) {
0185 diag = kdbgetularg((char *)argv[1], &cpu);
0186 if (diag)
0187 return diag;
0188 }
0189 if (cpu != ~0) {
0190 kdb_bt_cpu(cpu);
0191 } else {
0192
0193
0194
0195
0196 argv = NULL;
0197 kdb_printf("btc: cpu status: ");
0198 kdb_parse("cpu\n");
0199 for_each_online_cpu(cpu) {
0200 kdb_bt_cpu(cpu);
0201 touch_nmi_watchdog();
0202 }
0203 }
0204 return 0;
0205 } else {
0206 if (argc) {
0207 nextarg = 1;
0208 diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
0209 &offset, NULL);
0210 if (diag)
0211 return diag;
0212 kdb_show_stack(kdb_current_task, (void *)addr);
0213 return 0;
0214 } else {
0215 return kdb_bt1(kdb_current_task, "A", false);
0216 }
0217 }
0218
0219
0220 return 0;
0221 }