blob: 3de0cc780c164aea5c5fd4cf49cabe5795157734 [file] [log] [blame]
Jason Wessel5d5314d2010-05-20 21:04:20 -05001/*
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>
Ingo Molnar3f07c012017-02-08 18:51:30 +010015#include <linux/sched/signal.h>
Ingo Molnarb17b0152017-02-08 18:51:35 +010016#include <linux/sched/debug.h>
Jason Wessel5d5314d2010-05-20 21:04:20 -050017#include <linux/kdb.h>
18#include <linux/nmi.h>
Jason Wessel5d5314d2010-05-20 21:04:20 -050019#include "kdb_private.h"
20
21
22static void kdb_show_stack(struct task_struct *p, void *addr)
23{
24 int old_lvl = console_loglevel;
Douglas Anderson2277b492019-09-25 13:02:20 -070025
Borislav Petkova8fe19e2014-06-04 16:11:46 -070026 console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
Jason Wesseld37d39a2010-05-20 21:04:27 -050027 kdb_trap_printk++;
Douglas Anderson2277b492019-09-25 13:02:20 -070028
29 if (!addr && kdb_task_has_cpu(p))
30 kdb_dump_stack_on_cpu(kdb_process_cpu(p));
31 else
32 show_stack(p, addr);
33
Jason Wessel5d5314d2010-05-20 21:04:20 -050034 console_loglevel = old_lvl;
Jason Wesseld37d39a2010-05-20 21:04:27 -050035 kdb_trap_printk--;
Jason Wessel5d5314d2010-05-20 21:04:20 -050036}
37
38/*
39 * kdb_bt
40 *
41 * This function implements the 'bt' command. Print a stack
42 * traceback.
43 *
44 * bt [<address-expression>] (addr-exp is for alternate stacks)
45 * btp <pid> Kernel stack for <pid>
46 * btt <address-expression> Kernel stack for task structure at
47 * <address-expression>
48 * bta [DRSTCZEUIMA] All useful processes, optionally
49 * filtered by state
50 * btc [<cpu>] The current process on one cpu,
51 * default is all cpus
52 *
53 * bt <address-expression> refers to a address on the stack, that location
54 * is assumed to contain a return address.
55 *
56 * btt <address-expression> refers to the address of a struct task.
57 *
58 * Inputs:
59 * argc argument count
60 * argv argument vector
61 * Outputs:
62 * None.
63 * Returns:
64 * zero for success, a kdb diagnostic if error
65 * Locking:
66 * none.
67 * Remarks:
68 * Backtrack works best when the code uses frame pointers. But even
69 * without frame pointers we should get a reasonable trace.
70 *
71 * mds comes in handy when examining the stack to do a manual traceback or
72 * to get a starting point for bt <address-expression>.
73 */
74
75static int
Douglas Anderson54af3e32019-09-25 13:02:18 -070076kdb_bt1(struct task_struct *p, unsigned long mask, bool btaprompt)
Jason Wessel5d5314d2010-05-20 21:04:20 -050077{
Daniel Thompson4f27e822019-10-25 08:33:26 +010078 char ch;
79
80 if (kdb_getarea(ch, (unsigned long)p) ||
81 kdb_getarea(ch, (unsigned long)(p+1)-1))
Jason Wessel5d5314d2010-05-20 21:04:20 -050082 return KDB_BADADDR;
83 if (!kdb_task_state(p, mask))
84 return 0;
85 kdb_printf("Stack traceback for pid %d\n", p->pid);
86 kdb_ps1(p);
87 kdb_show_stack(p, NULL);
88 if (btaprompt) {
Daniel Thompson4f27e822019-10-25 08:33:26 +010089 kdb_printf("Enter <q> to end, <cr> or <space> to continue:");
90 do {
91 ch = kdb_getchar();
92 } while (!strchr("\r\n q", ch));
93 kdb_printf("\n");
94
95 /* reset the pager */
96 kdb_nextline = 1;
97
98 if (ch == 'q')
Jason Wessel5d5314d2010-05-20 21:04:20 -050099 return 1;
Jason Wessel5d5314d2010-05-20 21:04:20 -0500100 }
101 touch_nmi_watchdog();
102 return 0;
103}
104
Douglas Anderson55a7e232019-09-25 13:02:19 -0700105static void
106kdb_bt_cpu(unsigned long cpu)
107{
108 struct task_struct *kdb_tsk;
109
110 if (cpu >= num_possible_cpus() || !cpu_online(cpu)) {
111 kdb_printf("WARNING: no process for cpu %ld\n", cpu);
112 return;
113 }
114
115 /* If a CPU failed to round up we could be here */
116 kdb_tsk = KDB_TSK(cpu);
117 if (!kdb_tsk) {
118 kdb_printf("WARNING: no task for cpu %ld\n", cpu);
119 return;
120 }
121
Douglas Anderson55a7e232019-09-25 13:02:19 -0700122 kdb_bt1(kdb_tsk, ~0UL, false);
123}
124
Jason Wessel5d5314d2010-05-20 21:04:20 -0500125int
126kdb_bt(int argc, const char **argv)
127{
128 int diag;
Jason Wessel5d5314d2010-05-20 21:04:20 -0500129 int btaprompt = 1;
130 int nextarg;
131 unsigned long addr;
132 long offset;
133
Jason Wessel3bdb65e2011-06-30 14:12:00 -0500134 /* Prompt after each proc in bta */
135 kdbgetintenv("BTAPROMPT", &btaprompt);
Jason Wessel5d5314d2010-05-20 21:04:20 -0500136
137 if (strcmp(argv[0], "bta") == 0) {
138 struct task_struct *g, *p;
139 unsigned long cpu;
140 unsigned long mask = kdb_task_state_string(argc ? argv[1] :
141 NULL);
142 if (argc == 0)
143 kdb_ps_suppressed();
144 /* Run the active tasks first */
145 for_each_online_cpu(cpu) {
146 p = kdb_curr_task(cpu);
Douglas Anderson54af3e32019-09-25 13:02:18 -0700147 if (kdb_bt1(p, mask, btaprompt))
Jason Wessel5d5314d2010-05-20 21:04:20 -0500148 return 0;
149 }
150 /* Now the inactive tasks */
151 kdb_do_each_thread(g, p) {
Jason Wesseld1871b32012-08-26 21:43:12 -0500152 if (KDB_FLAG(CMD_INTERRUPT))
153 return 0;
Jason Wessel5d5314d2010-05-20 21:04:20 -0500154 if (task_curr(p))
155 continue;
Douglas Anderson54af3e32019-09-25 13:02:18 -0700156 if (kdb_bt1(p, mask, btaprompt))
Jason Wessel5d5314d2010-05-20 21:04:20 -0500157 return 0;
158 } kdb_while_each_thread(g, p);
159 } else if (strcmp(argv[0], "btp") == 0) {
160 struct task_struct *p;
161 unsigned long pid;
162 if (argc != 1)
163 return KDB_ARGCOUNT;
164 diag = kdbgetularg((char *)argv[1], &pid);
165 if (diag)
166 return diag;
167 p = find_task_by_pid_ns(pid, &init_pid_ns);
Douglas Anderson9441d5f2019-11-09 11:16:43 -0800168 if (p)
Douglas Anderson54af3e32019-09-25 13:02:18 -0700169 return kdb_bt1(p, ~0UL, false);
Jason Wessel5d5314d2010-05-20 21:04:20 -0500170 kdb_printf("No process with pid == %ld found\n", pid);
171 return 0;
172 } else if (strcmp(argv[0], "btt") == 0) {
173 if (argc != 1)
174 return KDB_ARGCOUNT;
175 diag = kdbgetularg((char *)argv[1], &addr);
176 if (diag)
177 return diag;
Douglas Anderson54af3e32019-09-25 13:02:18 -0700178 return kdb_bt1((struct task_struct *)addr, ~0UL, false);
Jason Wessel5d5314d2010-05-20 21:04:20 -0500179 } else if (strcmp(argv[0], "btc") == 0) {
180 unsigned long cpu = ~0;
Jason Wessel5d5314d2010-05-20 21:04:20 -0500181 if (argc > 1)
182 return KDB_ARGCOUNT;
183 if (argc == 1) {
184 diag = kdbgetularg((char *)argv[1], &cpu);
185 if (diag)
186 return diag;
187 }
Jason Wessel5d5314d2010-05-20 21:04:20 -0500188 if (cpu != ~0) {
Douglas Anderson55a7e232019-09-25 13:02:19 -0700189 kdb_bt_cpu(cpu);
190 } else {
191 /*
192 * Recursive use of kdb_parse, do not use argv after
193 * this point.
194 */
195 argv = NULL;
196 kdb_printf("btc: cpu status: ");
197 kdb_parse("cpu\n");
198 for_each_online_cpu(cpu) {
199 kdb_bt_cpu(cpu);
200 touch_nmi_watchdog();
Jason Wessel5d5314d2010-05-20 21:04:20 -0500201 }
Jason Wessel5d5314d2010-05-20 21:04:20 -0500202 }
Jason Wessel5d5314d2010-05-20 21:04:20 -0500203 return 0;
204 } else {
205 if (argc) {
206 nextarg = 1;
207 diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
208 &offset, NULL);
209 if (diag)
210 return diag;
211 kdb_show_stack(kdb_current_task, (void *)addr);
212 return 0;
213 } else {
Douglas Anderson54af3e32019-09-25 13:02:18 -0700214 return kdb_bt1(kdb_current_task, ~0UL, false);
Jason Wessel5d5314d2010-05-20 21:04:20 -0500215 }
216 }
217
218 /* NOTREACHED */
219 return 0;
220}