Drop obsoleted patch.
[linux-flexiantxendom0-3.2.10.git] / kdb / kdb_bt.c
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  */
10
11 #include <linux/ctype.h>
12 #include <linux/string.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/kdb.h>
16 #include <linux/kdbprivate.h>
17 #include <linux/nmi.h>
18 #include <asm/system.h>
19
20
21 /*
22  * kdb_bt
23  *
24  *      This function implements the 'bt' command.  Print a stack
25  *      traceback.
26  *
27  *      bt [<address-expression>]       (addr-exp is for alternate stacks)
28  *      btp <pid>                       Kernel stack for <pid>
29  *      btt <address-expression>        Kernel stack for task structure at <address-expression>
30  *      bta [DRSTCZEUIMA]               All useful processes, optionally filtered by state
31  *      btc [<cpu>]                     The current process on one cpu, default is all cpus
32  *
33  *      address expression refers to a return address on the stack.  It
34  *      is expected to be preceeded by a frame pointer.
35  *
36  * Inputs:
37  *      argc    argument count
38  *      argv    argument vector
39  *      envp    environment vector
40  *      regs    registers at time kdb was entered.
41  * Outputs:
42  *      None.
43  * Returns:
44  *      zero for success, a kdb diagnostic if error
45  * Locking:
46  *      none.
47  * Remarks:
48  *      Backtrack works best when the code uses frame pointers.  But
49  *      even without frame pointers we should get a reasonable trace.
50  *
51  *      mds comes in handy when examining the stack to do a manual
52  *      traceback.
53  */
54
55 static int
56 kdb_bt1(struct task_struct *p, unsigned long mask, int argcount, int btaprompt)
57 {
58         int diag;
59         char buffer[2];
60         /* FIXME: use kdb_verify_area */
61         if (kdb_getarea(buffer[0], (unsigned long)p) ||
62             kdb_getarea(buffer[0], (unsigned long)(p+1)-1))
63                 return KDB_BADADDR;
64         if (!kdb_task_state(p, mask))
65                 return 0;
66         kdb_printf("Stack traceback for pid %d\n", p->pid);
67         kdb_ps1(p);
68         diag = kdba_bt_process(p, argcount);
69         if (btaprompt) {
70                 kdb_getstr(buffer, sizeof(buffer), "Enter <q> to end, <cr> to continue:");
71                 if (buffer[0] == 'q') {
72                         kdb_printf("\n");
73                         return 1;
74                 }
75         }
76         touch_nmi_watchdog();
77         return 0;
78 }
79
80 int
81 kdb_bt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
82 {
83         int diag;
84         int argcount = 5;
85         int btaprompt = 1;
86         int nextarg;
87         unsigned long addr;
88         long offset;
89
90         kdbgetintenv("BTARGS", &argcount);      /* Arguments to print */
91         kdbgetintenv("BTAPROMPT", &btaprompt);  /* Prompt after each proc in bta */
92
93         if (strcmp(argv[0], "bta") == 0) {
94                 struct task_struct *g, *p;
95                 unsigned long cpu;
96                 unsigned long mask = kdb_task_state_string(argc ? argv[1] : NULL);
97                 if (argc == 0)
98                         kdb_ps_suppressed();
99                 /* Run the active tasks first */
100                 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
101                         if (!cpu_online(cpu))
102                                 continue;
103                         p = kdb_cpu_curr(cpu);
104                         if (kdb_bt1(p, mask, argcount, btaprompt))
105                                 return 0;
106                 }
107                 /* Now the inactive tasks */
108                 kdb_do_each_thread(g, p) {
109                         if (task_curr(p))
110                                 continue;
111                         if (kdb_bt1(p, mask, argcount, btaprompt))
112                                 return 0;
113                 } kdb_while_each_thread(g, p);
114         } else if (strcmp(argv[0], "btp") == 0) {
115                 struct task_struct *p;
116                 unsigned long pid;
117                 if (argc != 1)
118                         return KDB_ARGCOUNT;
119                 if ((diag = kdbgetularg((char *)argv[1], &pid)))
120                         return diag;
121                 if ((p = find_task_by_pid(pid)))
122                         return kdb_bt1(p, ~0UL, argcount, 0);
123                 kdb_printf("No process with pid == %ld found\n", pid);
124                 return 0;
125         } else if (strcmp(argv[0], "btt") == 0) {
126                 unsigned long addr;
127                 if (argc != 1)
128                         return KDB_ARGCOUNT;
129                 if ((diag = kdbgetularg((char *)argv[1], &addr)))
130                         return diag;
131                 return kdb_bt1((struct task_struct *)addr, ~0UL, argcount, 0);
132         } else if (strcmp(argv[0], "btc") == 0) {
133                 unsigned long cpu = ~0;
134                 struct kdb_running_process *krp;
135                 char buf[80];
136                 if (argc > 1)
137                         return KDB_ARGCOUNT;
138                 if (argc == 1 && (diag = kdbgetularg((char *)argv[1], &cpu)))
139                         return diag;
140                 /* Recursive use of kdb_parse, do not use argv after this point */
141                 argv = NULL;
142                 if (cpu != ~0) {
143                         krp = kdb_running_process + cpu;
144                         if (cpu >= NR_CPUS || !krp->seqno || !cpu_online(cpu)) {
145                                 kdb_printf("no process for cpu %ld\n", cpu);
146                                 return 0;
147                         }
148                         sprintf(buf, "btt 0x%p\n", krp->p);
149                         kdb_parse(buf, regs);
150                         return 0;
151                 }
152                 kdb_printf("btc: cpu status: ");
153                 kdb_parse("cpu\n", regs);
154                 for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) {
155                         if (!cpu_online(cpu) || !krp->seqno)
156                                 continue;
157                         sprintf(buf, "btt 0x%p\n", krp->p);
158                         kdb_parse(buf, regs);
159                         touch_nmi_watchdog();
160                 }
161                 return 0;
162         } else {
163                 if (argc) {
164                         nextarg = 1;
165                         diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
166                                              &offset, NULL, regs);
167                         if (diag)
168                                 return diag;
169                         return kdba_bt_address(addr, argcount);
170                 } else {
171                         return kdb_bt1(current, ~0UL, argcount, 0);
172                 }
173         }
174
175         /* NOTREACHED */
176         return 0;
177 }