1 /* $NetBSD: db_xxx.c,v 1.28 2003/09/20 03:02:04 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989, 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 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 17 * without specific prior written permission. 18 * 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 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 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 29 * SUCH DAMAGE. 30 * 31 * from: kern_proc.c 8.4 (Berkeley) 1/4/94 32 */ 33 34 /* 35 * Miscellaneous DDB functions that are intimate (xxx) with various 36 * data structures and functions used by the kernel (proc, callout). 37 */ 38 39 #include "opt_kgdb.h" 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: db_xxx.c,v 1.28 2003/09/20 03:02:04 thorpej Exp $"); 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/proc.h> 48 #include <sys/msgbuf.h> 49 50 #include <sys/callout.h> 51 #include <sys/signalvar.h> 52 #include <sys/resourcevar.h> 53 54 #include <machine/db_machdep.h> 55 56 #include <ddb/db_access.h> 57 #include <ddb/db_command.h> 58 #include <ddb/db_interface.h> 59 #include <ddb/db_lex.h> 60 #include <ddb/db_output.h> 61 #include <ddb/db_sym.h> 62 #include <ddb/db_extern.h> 63 #ifdef KGDB 64 #include <sys/kgdb.h> 65 #endif 66 67 void 68 db_kill_proc(db_expr_t addr, int haddr, db_expr_t count, char *modif) 69 { 70 struct proc *p; 71 db_expr_t pid, sig; 72 int t; 73 74 /* What pid? */ 75 if (!db_expression(&pid)) { 76 db_error("pid?\n"); 77 /*NOTREACHED*/ 78 } 79 /* What sig? */ 80 t = db_read_token(); 81 if (t == tCOMMA) { 82 if (!db_expression(&sig)) { 83 db_error("sig?\n"); 84 /*NOTREACHED*/ 85 } 86 } else { 87 db_unread_token(t); 88 sig = 15; 89 } 90 if (db_read_token() != tEOL) { 91 db_error("?\n"); 92 /*NOTREACHED*/ 93 } 94 95 p = pfind((pid_t)pid); 96 if (p == NULL) { 97 db_error("no such proc\n"); 98 /*NOTREACHED*/ 99 } 100 psignal(p, (int)sig); 101 } 102 103 #ifdef KGDB 104 void 105 db_kgdb_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif) 106 { 107 kgdb_active++; 108 kgdb_trap(db_trap_type, DDB_REGS); 109 kgdb_active--; 110 } 111 #endif 112 113 void 114 db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif) 115 { 116 int i; 117 118 char *mode; 119 struct proc *p, *pp, *cp; 120 struct lwp *l, *cl; 121 struct timeval tv[2]; 122 const struct proclist_desc *pd; 123 124 if (modif[0] == 0) 125 modif[0] = 'n'; /* default == normal mode */ 126 127 mode = strchr("mawln", modif[0]); 128 if (mode == NULL || *mode == 'm') { 129 db_printf("usage: show all procs [/a] [/n] [/w]\n"); 130 db_printf("\t/a == show process address info\n"); 131 db_printf("\t/l == show LWP info\n"); 132 db_printf("\t/n == show normal process info [default]\n"); 133 db_printf("\t/w == show process wait/emul info\n"); 134 return; 135 } 136 137 switch (*mode) { 138 case 'a': 139 db_printf(" PID %10s %18s %18s %18s\n", 140 "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP"); 141 break; 142 case 'l': 143 db_printf(" PID %4s S %9s %18s %18s %-12s\n", 144 "LID", "FLAGS", "STRUCT LWP *", "UAREA *", "WAIT"); 145 break; 146 case 'n': 147 db_printf(" PID %8s %8s %10s S %7s %4s %16s %7s\n", 148 "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT"); 149 break; 150 case 'w': 151 db_printf(" PID %10s %8s %4s %5s %5s %-12s%s\n", 152 "COMMAND", "EMUL", "PRI", "UTIME", "STIME", 153 "WAIT-MSG", "WAIT-CHANNEL"); 154 break; 155 } 156 157 /* XXX LOCKING XXX */ 158 pd = proclists; 159 cp = curproc; 160 cl = curlwp; 161 for (pd = proclists; pd->pd_list != NULL; pd++) { 162 LIST_FOREACH(p, pd->pd_list, p_list) { 163 pp = p->p_pptr; 164 if (p->p_stat == 0) { 165 continue; 166 } 167 l = LIST_FIRST(&p->p_lwps); 168 db_printf("%c%-10d", " >"[cp == p], p->p_pid); 169 170 switch (*mode) { 171 172 case 'a': 173 db_printf("%10.10s %18p %18p %18p\n", 174 p->p_comm, p, 175 l != NULL ? l->l_addr : 0, 176 p->p_vmspace); 177 break; 178 case 'l': 179 while (l != NULL) { 180 db_printf("%c%4d %d %#9x %18p %18p %s\n", 181 " >"[cl == l], l->l_lid, 182 l->l_stat, l->l_flag, l, 183 l->l_addr, 184 (l->l_wchan && l->l_wmesg) ? 185 l->l_wmesg : ""); 186 187 l = LIST_NEXT(l, l_sibling); 188 if (l) 189 db_printf("%11s",""); 190 } 191 break; 192 case 'n': 193 db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n", 194 pp ? pp->p_pid : -1, p->p_pgrp->pg_id, 195 p->p_cred->p_ruid, p->p_stat, p->p_flag, 196 p->p_nlwps, p->p_comm, 197 (p->p_nlwps != 1) ? "*" : ( 198 (l->l_wchan && l->l_wmesg) ? 199 l->l_wmesg : "")); 200 break; 201 202 case 'w': 203 db_printf("%10s %8s %4d", p->p_comm, 204 p->p_emul->e_name, 205 (l != NULL) ? l->l_priority : -1); 206 calcru(p, &tv[0], &tv[1], NULL); 207 for (i = 0; i < 2; ++i) { 208 db_printf("%4ld.%1ld", 209 (long)tv[i].tv_sec, 210 (long)tv[i].tv_usec/100000); 211 } 212 if (p->p_nlwps == 1) { 213 if (l->l_wchan && l->l_wmesg) { 214 db_printf(" %-12s", l->l_wmesg); 215 db_printsym( 216 (db_expr_t)(intptr_t)l->l_wchan, 217 DB_STGY_XTRN, db_printf); 218 } } else { 219 db_printf(" * "); 220 } 221 db_printf("\n"); 222 break; 223 224 } 225 } 226 } 227 } 228 229 void 230 db_dmesg(db_expr_t addr, int haddr, db_expr_t count, char *modif) 231 { 232 struct kern_msgbuf *mbp; 233 db_expr_t print; 234 int ch, newl, skip, i; 235 char *p, *bufdata; 236 237 if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { 238 db_printf("message buffer not available\n"); 239 return; 240 } 241 242 mbp = msgbufp; 243 bufdata = &mbp->msg_bufc[0]; 244 245 if (haddr && addr < mbp->msg_bufs) 246 print = addr; 247 else 248 print = mbp->msg_bufs; 249 250 for (newl = skip = i = 0, p = bufdata + mbp->msg_bufx; 251 i < mbp->msg_bufs; i++, p++) { 252 if (p == bufdata + mbp->msg_bufs) 253 p = bufdata; 254 if (i < mbp->msg_bufs - print) 255 continue; 256 ch = *p; 257 /* Skip "\n<.*>" syslog sequences. */ 258 if (skip) { 259 if (ch == '>') 260 newl = skip = 0; 261 continue; 262 } 263 if (newl && ch == '<') { 264 skip = 1; 265 continue; 266 } 267 if (ch == '\0') 268 continue; 269 newl = ch == '\n'; 270 db_printf("%c", ch); 271 } 272 if (!newl) 273 db_printf("\n"); 274 } 275 276 void 277 db_show_sched_qs(db_expr_t addr, int haddr, db_expr_t count, char *modif) 278 { 279 struct prochd *ph; 280 struct lwp *l; 281 int i, first; 282 283 for (i = 0; i < RUNQUE_NQS; i++) 284 { 285 first = 1; 286 ph = &sched_qs[i]; 287 for (l = ph->ph_link; l != (struct lwp *)ph; l = l->l_forw) { 288 if (first) { 289 db_printf("%c%d", 290 (sched_whichqs & (1U << i)) 291 ? ' ' : '!', i); 292 first = 0; 293 } 294 db_printf("\t%d.%d (%s)\n", l->l_proc->p_pid, 295 l->l_lid, l->l_proc->p_comm); 296 } 297 } 298 } 299