Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/kernel/debug/kdb/kdb_bt.c
17237 views
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 <asm/system.h>
19
#include "kdb_private.h"
20
21
22
static void kdb_show_stack(struct task_struct *p, void *addr)
23
{
24
int old_lvl = console_loglevel;
25
console_loglevel = 15;
26
kdb_trap_printk++;
27
kdb_set_current_task(p);
28
if (addr) {
29
show_stack((struct task_struct *)p, addr);
30
} else if (kdb_current_regs) {
31
#ifdef CONFIG_X86
32
show_stack(p, &kdb_current_regs->sp);
33
#else
34
show_stack(p, NULL);
35
#endif
36
} else {
37
show_stack(p, NULL);
38
}
39
console_loglevel = old_lvl;
40
kdb_trap_printk--;
41
}
42
43
/*
44
* kdb_bt
45
*
46
* This function implements the 'bt' command. Print a stack
47
* traceback.
48
*
49
* bt [<address-expression>] (addr-exp is for alternate stacks)
50
* btp <pid> Kernel stack for <pid>
51
* btt <address-expression> Kernel stack for task structure at
52
* <address-expression>
53
* bta [DRSTCZEUIMA] All useful processes, optionally
54
* filtered by state
55
* btc [<cpu>] The current process on one cpu,
56
* default is all cpus
57
*
58
* bt <address-expression> refers to a address on the stack, that location
59
* is assumed to contain a return address.
60
*
61
* btt <address-expression> refers to the address of a struct task.
62
*
63
* Inputs:
64
* argc argument count
65
* argv argument vector
66
* Outputs:
67
* None.
68
* Returns:
69
* zero for success, a kdb diagnostic if error
70
* Locking:
71
* none.
72
* Remarks:
73
* Backtrack works best when the code uses frame pointers. But even
74
* without frame pointers we should get a reasonable trace.
75
*
76
* mds comes in handy when examining the stack to do a manual traceback or
77
* to get a starting point for bt <address-expression>.
78
*/
79
80
static int
81
kdb_bt1(struct task_struct *p, unsigned long mask,
82
int argcount, int btaprompt)
83
{
84
char buffer[2];
85
if (kdb_getarea(buffer[0], (unsigned long)p) ||
86
kdb_getarea(buffer[0], (unsigned long)(p+1)-1))
87
return KDB_BADADDR;
88
if (!kdb_task_state(p, mask))
89
return 0;
90
kdb_printf("Stack traceback for pid %d\n", p->pid);
91
kdb_ps1(p);
92
kdb_show_stack(p, NULL);
93
if (btaprompt) {
94
kdb_getstr(buffer, sizeof(buffer),
95
"Enter <q> to end, <cr> to continue:");
96
if (buffer[0] == 'q') {
97
kdb_printf("\n");
98
return 1;
99
}
100
}
101
touch_nmi_watchdog();
102
return 0;
103
}
104
105
int
106
kdb_bt(int argc, const char **argv)
107
{
108
int diag;
109
int argcount = 5;
110
int btaprompt = 1;
111
int nextarg;
112
unsigned long addr;
113
long offset;
114
115
kdbgetintenv("BTARGS", &argcount); /* Arguments to print */
116
kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each
117
* proc in bta */
118
119
if (strcmp(argv[0], "bta") == 0) {
120
struct task_struct *g, *p;
121
unsigned long cpu;
122
unsigned long mask = kdb_task_state_string(argc ? argv[1] :
123
NULL);
124
if (argc == 0)
125
kdb_ps_suppressed();
126
/* Run the active tasks first */
127
for_each_online_cpu(cpu) {
128
p = kdb_curr_task(cpu);
129
if (kdb_bt1(p, mask, argcount, btaprompt))
130
return 0;
131
}
132
/* Now the inactive tasks */
133
kdb_do_each_thread(g, p) {
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
212