| @@ -1,295 +1,298 @@ | | | @@ -1,295 +1,298 @@ |
1 | /* $NetBSD: db_xxx.c,v 1.64 2011/06/12 03:35:51 rmind Exp $ */ | | 1 | /* $NetBSD: db_xxx.c,v 1.65 2011/12/02 23:57:58 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 | | 4 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. Neither the name of the University nor the names of its contributors | | 15 | * 3. Neither the name of the University nor the names of its contributors |
16 | * may be used to endorse or promote products derived from this software | | 16 | * may be used to endorse or promote products derived from this software |
17 | * without specific prior written permission. | | 17 | * without specific prior written permission. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 | * SUCH DAMAGE. | | 29 | * SUCH DAMAGE. |
30 | * | | 30 | * |
31 | * from: kern_proc.c 8.4 (Berkeley) 1/4/94 | | 31 | * from: kern_proc.c 8.4 (Berkeley) 1/4/94 |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | /* | | 34 | /* |
35 | * Miscellaneous DDB functions that are intimate (xxx) with various | | 35 | * Miscellaneous DDB functions that are intimate (xxx) with various |
36 | * data structures and functions used by the kernel (proc, callout). | | 36 | * data structures and functions used by the kernel (proc, callout). |
37 | */ | | 37 | */ |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | __KERNEL_RCSID(0, "$NetBSD: db_xxx.c,v 1.64 2011/06/12 03:35:51 rmind Exp $"); | | 40 | __KERNEL_RCSID(0, "$NetBSD: db_xxx.c,v 1.65 2011/12/02 23:57:58 christos Exp $"); |
41 | | | 41 | |
42 | #ifdef _KERNEL_OPT | | 42 | #ifdef _KERNEL_OPT |
43 | #include "opt_kgdb.h" | | 43 | #include "opt_kgdb.h" |
44 | #include "opt_aio.h" | | 44 | #include "opt_aio.h" |
45 | #include "opt_mqueue.h" | | 45 | #include "opt_mqueue.h" |
46 | #endif | | 46 | #endif |
47 | | | 47 | |
48 | #ifndef _KERNEL | | 48 | #ifndef _KERNEL |
49 | #include <stdbool.h> | | 49 | #include <stdbool.h> |
50 | #endif | | 50 | #endif |
51 | | | 51 | |
52 | #include <sys/param.h> | | 52 | #include <sys/param.h> |
53 | #include <sys/systm.h> | | 53 | #include <sys/systm.h> |
54 | #include <sys/kernel.h> | | 54 | #include <sys/kernel.h> |
55 | #include <sys/proc.h> | | 55 | #include <sys/proc.h> |
56 | #include <sys/msgbuf.h> | | 56 | #include <sys/msgbuf.h> |
57 | #include <sys/callout.h> | | 57 | #include <sys/callout.h> |
58 | #include <sys/file.h> | | 58 | #include <sys/file.h> |
59 | #include <sys/filedesc.h> | | 59 | #include <sys/filedesc.h> |
60 | #include <sys/lockdebug.h> | | 60 | #include <sys/lockdebug.h> |
61 | #include <sys/signalvar.h> | | 61 | #include <sys/signalvar.h> |
62 | #include <sys/resourcevar.h> | | 62 | #include <sys/resourcevar.h> |
63 | #include <sys/pool.h> | | 63 | #include <sys/pool.h> |
64 | #include <sys/uio.h> | | 64 | #include <sys/uio.h> |
65 | #include <sys/kauth.h> | | 65 | #include <sys/kauth.h> |
66 | #include <sys/mqueue.h> | | 66 | #include <sys/mqueue.h> |
67 | #include <sys/vnode.h> | | 67 | #include <sys/vnode.h> |
68 | #include <sys/module.h> | | 68 | #include <sys/module.h> |
69 | #include <sys/cpu.h> | | 69 | #include <sys/cpu.h> |
70 | #include <sys/vmem.h> | | 70 | #include <sys/vmem.h> |
71 | | | 71 | |
72 | #include <ddb/ddb.h> | | 72 | #include <ddb/ddb.h> |
73 | #include <ddb/db_user.h> | | 73 | #include <ddb/db_user.h> |
74 | | | 74 | |
75 | #ifdef KGDB | | 75 | #ifdef KGDB |
76 | #include <sys/kgdb.h> | | 76 | #include <sys/kgdb.h> |
77 | #endif | | 77 | #endif |
78 | | | 78 | |
79 | void | | 79 | void |
80 | db_kill_proc(db_expr_t addr, bool haddr, | | 80 | db_kill_proc(db_expr_t addr, bool haddr, |
81 | db_expr_t count, const char *modif) | | 81 | db_expr_t count, const char *modif) |
82 | { | | 82 | { |
83 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 83 | #ifdef _KERNEL /* XXX CRASH(8) */ |
84 | struct proc *p; | | 84 | struct proc *p; |
85 | ksiginfo_t ksi; | | 85 | ksiginfo_t ksi; |
86 | db_expr_t pid, sig; | | 86 | db_expr_t pid, sig; |
87 | int t; | | 87 | int t; |
88 | | | 88 | |
89 | /* What pid? */ | | 89 | /* What pid? */ |
90 | if (!db_expression(&pid)) { | | 90 | if (!db_expression(&pid)) { |
91 | db_error("pid?\n"); | | 91 | db_error("pid?\n"); |
92 | /*NOTREACHED*/ | | 92 | /*NOTREACHED*/ |
93 | } | | 93 | } |
94 | /* What sig? */ | | 94 | /* What sig? */ |
95 | t = db_read_token(); | | 95 | t = db_read_token(); |
96 | if (t == tCOMMA) { | | 96 | if (t == tCOMMA) { |
97 | if (!db_expression(&sig)) { | | 97 | if (!db_expression(&sig)) { |
98 | db_error("sig?\n"); | | 98 | db_error("sig?\n"); |
99 | /*NOTREACHED*/ | | 99 | /*NOTREACHED*/ |
100 | } | | 100 | } |
101 | } else { | | 101 | } else { |
102 | db_unread_token(t); | | 102 | db_unread_token(t); |
103 | sig = 15; | | 103 | sig = 15; |
104 | } | | 104 | } |
105 | if (db_read_token() != tEOL) { | | 105 | if (db_read_token() != tEOL) { |
106 | db_error("?\n"); | | 106 | db_error("?\n"); |
107 | /*NOTREACHED*/ | | 107 | /*NOTREACHED*/ |
108 | } | | 108 | } |
109 | | | 109 | /* We might stop when the mutex is held or when not */ |
| | | 110 | t = mutex_tryenter(proc_lock); |
110 | p = proc_find((pid_t)pid); | | 111 | p = proc_find((pid_t)pid); |
| | | 112 | if (t) |
| | | 113 | mutex_exit(proc_lock); |
111 | if (p == NULL) { | | 114 | if (p == NULL) { |
112 | db_error("no such proc\n"); | | 115 | db_error("no such proc\n"); |
113 | /*NOTREACHED*/ | | 116 | /*NOTREACHED*/ |
114 | } | | 117 | } |
115 | KSI_INIT(&ksi); | | 118 | KSI_INIT(&ksi); |
116 | ksi.ksi_signo = sig; | | 119 | ksi.ksi_signo = sig; |
117 | ksi.ksi_code = SI_USER; | | 120 | ksi.ksi_code = SI_USER; |
118 | ksi.ksi_pid = 0; | | 121 | ksi.ksi_pid = 0; |
119 | ksi.ksi_uid = 0; | | 122 | ksi.ksi_uid = 0; |
120 | kpsignal2(p, &ksi); | | 123 | kpsignal2(p, &ksi); |
121 | #else | | 124 | #else |
122 | db_printf("This command is not currently supported.\n"); | | 125 | db_printf("This command is not currently supported.\n"); |
123 | #endif | | 126 | #endif |
124 | } | | 127 | } |
125 | | | 128 | |
126 | #ifdef KGDB | | 129 | #ifdef KGDB |
127 | void | | 130 | void |
128 | db_kgdb_cmd(db_expr_t addr, bool haddr, | | 131 | db_kgdb_cmd(db_expr_t addr, bool haddr, |
129 | db_expr_t count, const char *modif) | | 132 | db_expr_t count, const char *modif) |
130 | { | | 133 | { |
131 | kgdb_active++; | | 134 | kgdb_active++; |
132 | kgdb_trap(db_trap_type, DDB_REGS); | | 135 | kgdb_trap(db_trap_type, DDB_REGS); |
133 | kgdb_active--; | | 136 | kgdb_active--; |
134 | } | | 137 | } |
135 | #endif | | 138 | #endif |
136 | | | 139 | |
137 | void | | 140 | void |
138 | db_show_files_cmd(db_expr_t addr, bool haddr, | | 141 | db_show_files_cmd(db_expr_t addr, bool haddr, |
139 | db_expr_t count, const char *modif) | | 142 | db_expr_t count, const char *modif) |
140 | { | | 143 | { |
141 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 144 | #ifdef _KERNEL /* XXX CRASH(8) */ |
142 | struct proc *p; | | 145 | struct proc *p; |
143 | int i; | | 146 | int i; |
144 | filedesc_t *fdp; | | 147 | filedesc_t *fdp; |
145 | fdfile_t *ff; | | 148 | fdfile_t *ff; |
146 | file_t *fp; | | 149 | file_t *fp; |
147 | struct vnode *vn; | | 150 | struct vnode *vn; |
148 | bool full = false; | | 151 | bool full = false; |
149 | fdtab_t *dt; | | 152 | fdtab_t *dt; |
150 | | | 153 | |
151 | if (modif[0] == 'f') | | 154 | if (modif[0] == 'f') |
152 | full = true; | | 155 | full = true; |
153 | | | 156 | |
154 | p = (struct proc *) (uintptr_t) addr; | | 157 | p = (struct proc *) (uintptr_t) addr; |
155 | | | 158 | |
156 | fdp = p->p_fd; | | 159 | fdp = p->p_fd; |
157 | dt = fdp->fd_dt; | | 160 | dt = fdp->fd_dt; |
158 | for (i = 0; i < dt->dt_nfiles; i++) { | | 161 | for (i = 0; i < dt->dt_nfiles; i++) { |
159 | if ((ff = dt->dt_ff[i]) == NULL) | | 162 | if ((ff = dt->dt_ff[i]) == NULL) |
160 | continue; | | 163 | continue; |
161 | | | 164 | |
162 | fp = ff->ff_file; | | 165 | fp = ff->ff_file; |
163 | | | 166 | |
164 | /* Only look at vnodes... */ | | 167 | /* Only look at vnodes... */ |
165 | if ((fp != NULL) && (fp->f_type == DTYPE_VNODE)) { | | 168 | if ((fp != NULL) && (fp->f_type == DTYPE_VNODE)) { |
166 | if (fp->f_data != NULL) { | | 169 | if (fp->f_data != NULL) { |
167 | vn = (struct vnode *) fp->f_data; | | 170 | vn = (struct vnode *) fp->f_data; |
168 | vfs_vnode_print(vn, full, db_printf); | | 171 | vfs_vnode_print(vn, full, db_printf); |
169 | | | 172 | |
170 | #ifdef LOCKDEBUG | | 173 | #ifdef LOCKDEBUG |
171 | db_printf("\nv_uobj.vmobjlock lock details:\n"); | | 174 | db_printf("\nv_uobj.vmobjlock lock details:\n"); |
172 | lockdebug_lock_print(vn->v_uobj.vmobjlock, | | 175 | lockdebug_lock_print(vn->v_uobj.vmobjlock, |
173 | db_printf); | | 176 | db_printf); |
174 | db_printf("\n"); | | 177 | db_printf("\n"); |
175 | #endif | | 178 | #endif |
176 | } | | 179 | } |
177 | } | | 180 | } |
178 | } | | 181 | } |
179 | #endif | | 182 | #endif |
180 | } | | 183 | } |
181 | | | 184 | |
182 | #ifdef AIO | | 185 | #ifdef AIO |
183 | void | | 186 | void |
184 | db_show_aio_jobs(db_expr_t addr, bool haddr, | | 187 | db_show_aio_jobs(db_expr_t addr, bool haddr, |
185 | db_expr_t count, const char *modif) | | 188 | db_expr_t count, const char *modif) |
186 | { | | 189 | { |
187 | | | 190 | |
188 | aio_print_jobs(db_printf); | | 191 | aio_print_jobs(db_printf); |
189 | } | | 192 | } |
190 | #endif | | 193 | #endif |
191 | | | 194 | |
192 | #ifdef MQUEUE | | 195 | #ifdef MQUEUE |
193 | void | | 196 | void |
194 | db_show_mqueue_cmd(db_expr_t addr, bool haddr, | | 197 | db_show_mqueue_cmd(db_expr_t addr, bool haddr, |
195 | db_expr_t count, const char *modif) | | 198 | db_expr_t count, const char *modif) |
196 | { | | 199 | { |
197 | | | 200 | |
198 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 201 | #ifdef _KERNEL /* XXX CRASH(8) */ |
199 | mqueue_print_list(db_printf); | | 202 | mqueue_print_list(db_printf); |
200 | #endif | | 203 | #endif |
201 | } | | 204 | } |
202 | #endif | | 205 | #endif |
203 | | | 206 | |
204 | void | | 207 | void |
205 | db_show_module_cmd(db_expr_t addr, bool haddr, | | 208 | db_show_module_cmd(db_expr_t addr, bool haddr, |
206 | db_expr_t count, const char *modif) | | 209 | db_expr_t count, const char *modif) |
207 | { | | 210 | { |
208 | | | 211 | |
209 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 212 | #ifdef _KERNEL /* XXX CRASH(8) */ |
210 | module_print_list(db_printf); | | 213 | module_print_list(db_printf); |
211 | #endif | | 214 | #endif |
212 | } | | 215 | } |
213 | | | 216 | |
214 | void | | 217 | void |
215 | db_show_all_pools(db_expr_t addr, bool haddr, | | 218 | db_show_all_pools(db_expr_t addr, bool haddr, |
216 | db_expr_t count, const char *modif) | | 219 | db_expr_t count, const char *modif) |
217 | { | | 220 | { |
218 | | | 221 | |
219 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 222 | #ifdef _KERNEL /* XXX CRASH(8) */ |
220 | pool_printall(modif, db_printf); | | 223 | pool_printall(modif, db_printf); |
221 | #endif | | 224 | #endif |
222 | } | | 225 | } |
223 | | | 226 | |
224 | void | | 227 | void |
225 | db_show_all_vmems(db_expr_t addr, bool have_addr, | | 228 | db_show_all_vmems(db_expr_t addr, bool have_addr, |
226 | db_expr_t count, const char *modif) | | 229 | db_expr_t count, const char *modif) |
227 | { | | 230 | { |
228 | | | 231 | |
229 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 232 | #ifdef _KERNEL /* XXX CRASH(8) */ |
230 | vmem_printall(modif, db_printf); | | 233 | vmem_printall(modif, db_printf); |
231 | #endif | | 234 | #endif |
232 | } | | 235 | } |
233 | | | 236 | |
234 | void | | 237 | void |
235 | db_dmesg(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) | | 238 | db_dmesg(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) |
236 | { | | 239 | { |
237 | struct kern_msgbuf mb, *mbp; | | 240 | struct kern_msgbuf mb, *mbp; |
238 | db_expr_t print; | | 241 | db_expr_t print; |
239 | int newl, skip, i; | | 242 | int newl, skip, i; |
240 | char *p, *bufdata, ch; | | 243 | char *p, *bufdata, ch; |
241 | | | 244 | |
242 | if (!db_read_int("msgbufenabled")) { | | 245 | if (!db_read_int("msgbufenabled")) { |
243 | db_printf("message buffer not available\n"); | | 246 | db_printf("message buffer not available\n"); |
244 | return; | | 247 | return; |
245 | } | | 248 | } |
246 | mbp = (struct kern_msgbuf *)db_read_ptr("msgbufp"); | | 249 | mbp = (struct kern_msgbuf *)db_read_ptr("msgbufp"); |
247 | db_read_bytes((db_addr_t)mbp, sizeof(mb), (char *)&mb); | | 250 | db_read_bytes((db_addr_t)mbp, sizeof(mb), (char *)&mb); |
248 | if (mb.msg_magic != MSG_MAGIC) { | | 251 | if (mb.msg_magic != MSG_MAGIC) { |
249 | db_printf("message buffer not available\n"); | | 252 | db_printf("message buffer not available\n"); |
250 | return; | | 253 | return; |
251 | } | | 254 | } |
252 | | | 255 | |
253 | bufdata = &mbp->msg_bufc[0]; | | 256 | bufdata = &mbp->msg_bufc[0]; |
254 | | | 257 | |
255 | if (haddr && addr < mb.msg_bufs) | | 258 | if (haddr && addr < mb.msg_bufs) |
256 | print = addr; | | 259 | print = addr; |
257 | else | | 260 | else |
258 | print = mb.msg_bufs; | | 261 | print = mb.msg_bufs; |
259 | | | 262 | |
260 | for (newl = skip = i = 0, p = bufdata + mb.msg_bufx; | | 263 | for (newl = skip = i = 0, p = bufdata + mb.msg_bufx; |
261 | i < mb.msg_bufs; i++, p++) { | | 264 | i < mb.msg_bufs; i++, p++) { |
262 | if (p == bufdata + mb.msg_bufs) | | 265 | if (p == bufdata + mb.msg_bufs) |
263 | p = bufdata; | | 266 | p = bufdata; |
264 | if (i < mb.msg_bufs - print) { | | 267 | if (i < mb.msg_bufs - print) { |
265 | continue; | | 268 | continue; |
266 | } | | 269 | } |
267 | db_read_bytes((db_addr_t)p, sizeof(ch), &ch); | | 270 | db_read_bytes((db_addr_t)p, sizeof(ch), &ch); |
268 | /* Skip "\n<.*>" syslog sequences. */ | | 271 | /* Skip "\n<.*>" syslog sequences. */ |
269 | if (skip) { | | 272 | if (skip) { |
270 | if (ch == '>') | | 273 | if (ch == '>') |
271 | newl = skip = 0; | | 274 | newl = skip = 0; |
272 | continue; | | 275 | continue; |
273 | } | | 276 | } |
274 | if (newl && ch == '<') { | | 277 | if (newl && ch == '<') { |
275 | skip = 1; | | 278 | skip = 1; |
276 | continue; | | 279 | continue; |
277 | } | | 280 | } |
278 | if (ch == '\0') | | 281 | if (ch == '\0') |
279 | continue; | | 282 | continue; |
280 | newl = ch == '\n'; | | 283 | newl = ch == '\n'; |
281 | db_printf("%c", ch); | | 284 | db_printf("%c", ch); |
282 | } | | 285 | } |
283 | if (!newl) | | 286 | if (!newl) |
284 | db_printf("\n"); | | 287 | db_printf("\n"); |
285 | } | | 288 | } |
286 | | | 289 | |
287 | void | | 290 | void |
288 | db_show_sched_qs(db_expr_t addr, bool haddr, | | 291 | db_show_sched_qs(db_expr_t addr, bool haddr, |
289 | db_expr_t count, const char *modif) | | 292 | db_expr_t count, const char *modif) |
290 | { | | 293 | { |
291 | | | 294 | |
292 | #ifdef _KERNEL /* XXX CRASH(8) */ | | 295 | #ifdef _KERNEL /* XXX CRASH(8) */ |
293 | sched_print_runqueue(db_printf); | | 296 | sched_print_runqueue(db_printf); |
294 | #endif | | 297 | #endif |
295 | } | | 298 | } |