Blame view

kernel/debug/kdb/kdb_bt.c 5.09 KB
5d5314d67   Jason Wessel   kdb: core for kgd...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * Kernel Debugger Architecture Independent Stack Traceback
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
   * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
   */
  
  #include <linux/ctype.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
3f07c0144   Ingo Molnar   sched/headers: Pr...
15
  #include <linux/sched/signal.h>
b17b01533   Ingo Molnar   sched/headers: Pr...
16
  #include <linux/sched/debug.h>
5d5314d67   Jason Wessel   kdb: core for kgd...
17
18
  #include <linux/kdb.h>
  #include <linux/nmi.h>
5d5314d67   Jason Wessel   kdb: core for kgd...
19
20
21
22
23
  #include "kdb_private.h"
  
  
  static void kdb_show_stack(struct task_struct *p, void *addr)
  {
d37d39ae3   Jason Wessel   printk,kdb: captu...
24
  	kdb_trap_printk++;
2277b4925   Douglas Anderson   kdb: Fix stack cr...
25

77819daf2   Dmitry Safonov   kdb: don't play w...
26
27
28
29
  	if (!addr && kdb_task_has_cpu(p)) {
  		int old_lvl = console_loglevel;
  
  		console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
2277b4925   Douglas Anderson   kdb: Fix stack cr...
30
  		kdb_dump_stack_on_cpu(kdb_process_cpu(p));
77819daf2   Dmitry Safonov   kdb: don't play w...
31
32
  		console_loglevel = old_lvl;
  	} else {
9cb8f069d   Dmitry Safonov   kernel: rename sh...
33
  		show_stack(p, addr, KERN_EMERG);
77819daf2   Dmitry Safonov   kdb: don't play w...
34
  	}
2277b4925   Douglas Anderson   kdb: Fix stack cr...
35

d37d39ae3   Jason Wessel   printk,kdb: captu...
36
  	kdb_trap_printk--;
5d5314d67   Jason Wessel   kdb: core for kgd...
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  }
  
  /*
   * kdb_bt
   *
   *	This function implements the 'bt' command.  Print a stack
   *	traceback.
   *
   *	bt [<address-expression>]	(addr-exp is for alternate stacks)
   *	btp <pid>			Kernel stack for <pid>
   *	btt <address-expression>	Kernel stack for task structure at
   *					<address-expression>
   *	bta [DRSTCZEUIMA]		All useful processes, optionally
   *					filtered by state
   *	btc [<cpu>]			The current process on one cpu,
   *					default is all cpus
   *
   *	bt <address-expression> refers to a address on the stack, that location
   *	is assumed to contain a return address.
   *
   *	btt <address-expression> refers to the address of a struct task.
   *
   * Inputs:
   *	argc	argument count
   *	argv	argument vector
   * Outputs:
   *	None.
   * Returns:
   *	zero for success, a kdb diagnostic if error
   * Locking:
   *	none.
   * Remarks:
   *	Backtrack works best when the code uses frame pointers.  But even
   *	without frame pointers we should get a reasonable trace.
   *
   *	mds comes in handy when examining the stack to do a manual traceback or
   *	to get a starting point for bt <address-expression>.
   */
  
  static int
54af3e39e   Douglas Anderson   kdb: Remove unuse...
77
  kdb_bt1(struct task_struct *p, unsigned long mask, bool btaprompt)
5d5314d67   Jason Wessel   kdb: core for kgd...
78
  {
4f27e824b   Daniel Thompson   kdb: Remove speci...
79
80
81
82
  	char ch;
  
  	if (kdb_getarea(ch, (unsigned long)p) ||
  	    kdb_getarea(ch, (unsigned long)(p+1)-1))
5d5314d67   Jason Wessel   kdb: core for kgd...
83
84
85
86
87
88
89
90
  		return KDB_BADADDR;
  	if (!kdb_task_state(p, mask))
  		return 0;
  	kdb_printf("Stack traceback for pid %d
  ", p->pid);
  	kdb_ps1(p);
  	kdb_show_stack(p, NULL);
  	if (btaprompt) {
4f27e824b   Daniel Thompson   kdb: Remove speci...
91
92
93
94
95
96
97
98
99
100
101
102
  		kdb_printf("Enter <q> to end, <cr> or <space> to continue:");
  		do {
  			ch = kdb_getchar();
  		} while (!strchr("\r
   q", ch));
  		kdb_printf("
  ");
  
  		/* reset the pager */
  		kdb_nextline = 1;
  
  		if (ch == 'q')
5d5314d67   Jason Wessel   kdb: core for kgd...
103
  			return 1;
5d5314d67   Jason Wessel   kdb: core for kgd...
104
105
106
107
  	}
  	touch_nmi_watchdog();
  	return 0;
  }
55a7e23f4   Douglas Anderson   kdb: Fix "btc <cp...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  static void
  kdb_bt_cpu(unsigned long cpu)
  {
  	struct task_struct *kdb_tsk;
  
  	if (cpu >= num_possible_cpus() || !cpu_online(cpu)) {
  		kdb_printf("WARNING: no process for cpu %ld
  ", cpu);
  		return;
  	}
  
  	/* If a CPU failed to round up we could be here */
  	kdb_tsk = KDB_TSK(cpu);
  	if (!kdb_tsk) {
  		kdb_printf("WARNING: no task for cpu %ld
  ", cpu);
  		return;
  	}
55a7e23f4   Douglas Anderson   kdb: Fix "btc <cp...
126
127
  	kdb_bt1(kdb_tsk, ~0UL, false);
  }
5d5314d67   Jason Wessel   kdb: core for kgd...
128
129
130
131
  int
  kdb_bt(int argc, const char **argv)
  {
  	int diag;
5d5314d67   Jason Wessel   kdb: core for kgd...
132
133
134
135
  	int btaprompt = 1;
  	int nextarg;
  	unsigned long addr;
  	long offset;
3bdb65ec9   Jason Wessel   kdb: cleanup unus...
136
137
  	/* Prompt after each proc in bta */
  	kdbgetintenv("BTAPROMPT", &btaprompt);
5d5314d67   Jason Wessel   kdb: core for kgd...
138
139
140
141
142
143
144
145
146
147
148
  
  	if (strcmp(argv[0], "bta") == 0) {
  		struct task_struct *g, *p;
  		unsigned long cpu;
  		unsigned long mask = kdb_task_state_string(argc ? argv[1] :
  							   NULL);
  		if (argc == 0)
  			kdb_ps_suppressed();
  		/* Run the active tasks first */
  		for_each_online_cpu(cpu) {
  			p = kdb_curr_task(cpu);
54af3e39e   Douglas Anderson   kdb: Remove unuse...
149
  			if (kdb_bt1(p, mask, btaprompt))
5d5314d67   Jason Wessel   kdb: core for kgd...
150
151
152
  				return 0;
  		}
  		/* Now the inactive tasks */
ece4ceaf2   Davidlohr Bueso   kdb: Use newer ap...
153
  		for_each_process_thread(g, p) {
d1871b38f   Jason Wessel   kdb: Fix dmesg/bt...
154
155
  			if (KDB_FLAG(CMD_INTERRUPT))
  				return 0;
5d5314d67   Jason Wessel   kdb: core for kgd...
156
157
  			if (task_curr(p))
  				continue;
54af3e39e   Douglas Anderson   kdb: Remove unuse...
158
  			if (kdb_bt1(p, mask, btaprompt))
5d5314d67   Jason Wessel   kdb: core for kgd...
159
  				return 0;
ece4ceaf2   Davidlohr Bueso   kdb: Use newer ap...
160
  		}
5d5314d67   Jason Wessel   kdb: core for kgd...
161
162
163
164
165
166
167
168
169
  	} else if (strcmp(argv[0], "btp") == 0) {
  		struct task_struct *p;
  		unsigned long pid;
  		if (argc != 1)
  			return KDB_ARGCOUNT;
  		diag = kdbgetularg((char *)argv[1], &pid);
  		if (diag)
  			return diag;
  		p = find_task_by_pid_ns(pid, &init_pid_ns);
9441d5f6b   Douglas Anderson   kdb: Gid rid of i...
170
  		if (p)
54af3e39e   Douglas Anderson   kdb: Remove unuse...
171
  			return kdb_bt1(p, ~0UL, false);
5d5314d67   Jason Wessel   kdb: core for kgd...
172
173
174
175
176
177
178
179
180
  		kdb_printf("No process with pid == %ld found
  ", pid);
  		return 0;
  	} else if (strcmp(argv[0], "btt") == 0) {
  		if (argc != 1)
  			return KDB_ARGCOUNT;
  		diag = kdbgetularg((char *)argv[1], &addr);
  		if (diag)
  			return diag;
54af3e39e   Douglas Anderson   kdb: Remove unuse...
181
  		return kdb_bt1((struct task_struct *)addr, ~0UL, false);
5d5314d67   Jason Wessel   kdb: core for kgd...
182
183
  	} else if (strcmp(argv[0], "btc") == 0) {
  		unsigned long cpu = ~0;
5d5314d67   Jason Wessel   kdb: core for kgd...
184
185
186
187
188
189
190
  		if (argc > 1)
  			return KDB_ARGCOUNT;
  		if (argc == 1) {
  			diag = kdbgetularg((char *)argv[1], &cpu);
  			if (diag)
  				return diag;
  		}
5d5314d67   Jason Wessel   kdb: core for kgd...
191
  		if (cpu != ~0) {
55a7e23f4   Douglas Anderson   kdb: Fix "btc <cp...
192
193
194
195
196
197
198
199
200
201
202
203
204
  			kdb_bt_cpu(cpu);
  		} else {
  			/*
  			 * Recursive use of kdb_parse, do not use argv after
  			 * this point.
  			 */
  			argv = NULL;
  			kdb_printf("btc: cpu status: ");
  			kdb_parse("cpu
  ");
  			for_each_online_cpu(cpu) {
  				kdb_bt_cpu(cpu);
  				touch_nmi_watchdog();
162bc7f5a   Douglas Anderson   kdb: Don't back t...
205
  			}
5d5314d67   Jason Wessel   kdb: core for kgd...
206
  		}
5d5314d67   Jason Wessel   kdb: core for kgd...
207
208
209
210
211
212
213
214
215
216
217
  		return 0;
  	} else {
  		if (argc) {
  			nextarg = 1;
  			diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
  					     &offset, NULL);
  			if (diag)
  				return diag;
  			kdb_show_stack(kdb_current_task, (void *)addr);
  			return 0;
  		} else {
54af3e39e   Douglas Anderson   kdb: Remove unuse...
218
  			return kdb_bt1(kdb_current_task, ~0UL, false);
5d5314d67   Jason Wessel   kdb: core for kgd...
219
220
221
222
223
224
  		}
  	}
  
  	/* NOTREACHED */
  	return 0;
  }