1 /*- 2 * Copyright (c) 1993 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/cons.h> 35 #include <sys/jail.h> 36 #include <sys/kdb.h> 37 #include <sys/linker_set.h> 38 #include <sys/proc.h> 39 #include <sys/sysent.h> 40 #include <sys/systm.h> 41 #include <vm/vm.h> 42 #include <vm/vm_param.h> 43 #include <vm/pmap.h> 44 45 #include <ddb/ddb.h> 46 47 /* XXX I'd prefer a better way. */ 48 #if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) 49 #define PTR64 50 #endif 51 52 #ifdef PTR64 53 CTASSERT(sizeof(uintptr_t) == sizeof(uint64_t)); 54 #else 55 CTASSERT(sizeof(uintptr_t) == sizeof(uint32_t)); 56 #endif 57 58 static void dumpthread(volatile struct proc *p, volatile struct thread *td, 59 int all); 60 61 /* 62 * Layout: 63 * - column counts 64 * - header 65 * - single-threaded process 66 * - multi-threaded process 67 * - thread in a MT process 68 * 69 * 1 2 3 4 5 6 7 70 * 1234567890123456789012345678901234567890123456789012345678901234567890 71 * pid uid ppid pgrp state wmesg wchan cmd 72 * <pid> <ui> <ppi> <pgi> <stat> < wmesg > < wchan > <name> 73 * <pid> <ui> <ppi> <pgi> <stat> (threaded) <command> 74 * <tid > <stat> < wmesg > < wchan > <name> 75 * 76 * For machines with 64-bit pointers, we expand the wchan field 8 more 77 * characters. 78 */ 79 void 80 db_ps(db_expr_t addr, boolean_t hasaddr, db_expr_t count, char *modif) 81 { 82 volatile struct proc *p, *pp; 83 volatile struct thread *td; 84 struct ucred *cred; 85 struct pgrp *pgrp; 86 char state[9]; 87 int np, quit, rflag, sflag, dflag, lflag, wflag; 88 89 np = nprocs; 90 quit = 0; 91 92 if (!LIST_EMPTY(&allproc)) 93 p = LIST_FIRST(&allproc); 94 else 95 p = &proc0; 96 97 db_setup_paging(db_simple_pager, &quit, db_lines_per_page); 98 #ifdef PTR64 99 db_printf(" pid uid ppid pgrp state wmesg wchan cmd\n"); 100 #else 101 db_printf(" pid uid ppid pgrp state wmesg wchan cmd\n"); 102 #endif 103 while (--np >= 0 && !quit) { 104 if (p == NULL) { 105 db_printf("oops, ran out of processes early!\n"); 106 break; 107 } 108 pp = p->p_pptr; 109 if (pp == NULL) 110 pp = p; 111 112 cred = p->p_ucred; 113 pgrp = p->p_pgrp; 114 db_printf("%5d %4d %5d %5d ", p->p_pid, 115 cred != NULL ? cred->cr_ruid : 0, pp->p_pid, 116 pgrp != NULL ? pgrp->pg_id : 0); 117 118 /* Determine our primary process state. */ 119 switch (p->p_state) { 120 case PRS_NORMAL: 121 if (P_SHOULDSTOP(p)) 122 state[0] = 'T'; 123 else { 124 /* 125 * One of D, L, R, S, W. For a 126 * multithreaded process we will use 127 * the state of the thread with the 128 * highest precedence. The 129 * precendence order from high to low 130 * is R, L, D, S, W. If no thread is 131 * in a sane state we use '?' for our 132 * primary state. 133 */ 134 rflag = sflag = dflag = lflag = wflag = 0; 135 FOREACH_THREAD_IN_PROC(p, td) { 136 if (td->td_state == TDS_RUNNING || 137 td->td_state == TDS_RUNQ || 138 td->td_state == TDS_CAN_RUN) 139 rflag++; 140 if (TD_ON_LOCK(td)) 141 lflag++; 142 if (TD_IS_SLEEPING(td)) { 143 if (!td->td_flags & TDF_SINTR) 144 dflag++; 145 else 146 sflag++; 147 } 148 if (TD_AWAITING_INTR(td)) 149 wflag++; 150 } 151 if (rflag) 152 state[0] = 'R'; 153 else if (lflag) 154 state[0] = 'L'; 155 else if (dflag) 156 state[0] = 'D'; 157 else if (sflag) 158 state[0] = 'S'; 159 else if (wflag) 160 state[0] = 'W'; 161 else 162 state[0] = '?'; 163 } 164 break; 165 case PRS_NEW: 166 state[0] = 'N'; 167 break; 168 case PRS_ZOMBIE: 169 state[0] = 'Z'; 170 break; 171 default: 172 state[0] = 'U'; 173 break; 174 } 175 state[1] = '\0'; 176 177 /* Additional process state flags. */ 178 if (!p->p_sflag & PS_INMEM) 179 strlcat(state, "W", sizeof(state)); 180 if (p->p_flag & P_TRACED) 181 strlcat(state, "X", sizeof(state)); 182 if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE) 183 strlcat(state, "E", sizeof(state)); 184 if (p->p_flag & P_PPWAIT) 185 strlcat(state, "V", sizeof(state)); 186 if (p->p_flag & P_SYSTEM || p->p_lock > 0) 187 strlcat(state, "L", sizeof(state)); 188 if (p->p_session != NULL && SESS_LEADER(p)) 189 strlcat(state, "s", sizeof(state)); 190 /* Cheated here and didn't compare pgid's. */ 191 if (p->p_flag & P_CONTROLT) 192 strlcat(state, "+", sizeof(state)); 193 if (cred != NULL && jailed(cred)) 194 strlcat(state, "J", sizeof(state)); 195 db_printf(" %-6.6s ", state); 196 if (p->p_flag & P_HADTHREADS) 197 #ifdef PTR64 198 db_printf(" (threaded) %s\n", 199 p->p_comm); 200 #else 201 db_printf(" (threaded) %s\n", p->p_comm); 202 #endif 203 FOREACH_THREAD_IN_PROC(p, td) { 204 dumpthread(p, td, p->p_flag & P_HADTHREADS); 205 if (quit) 206 break; 207 } 208 209 p = LIST_NEXT(p, p_list); 210 if (p == NULL && np > 0) 211 p = LIST_FIRST(&zombproc); 212 } 213 } 214 215 static void 216 dumpthread(volatile struct proc *p, volatile struct thread *td, int all) 217 { 218 char state[9], wprefix; 219 const char *wmesg; 220 void *wchan; 221 222 if (all) { 223 db_printf(" %9d ", td->td_tid); 224 switch (td->td_state) { 225 case TDS_RUNNING: 226 snprintf(state, sizeof(state), "Run"); 227 break; 228 case TDS_RUNQ: 229 snprintf(state, sizeof(state), "RunQ"); 230 break; 231 case TDS_CAN_RUN: 232 snprintf(state, sizeof(state), "CanRun"); 233 break; 234 case TDS_INACTIVE: 235 snprintf(state, sizeof(state), "Inactv"); 236 break; 237 case TDS_INHIBITED: 238 state[0] = '\0'; 239 if (TD_ON_LOCK(td)) 240 strlcat(state, "L", sizeof(state)); 241 if (TD_IS_SLEEPING(td)) { 242 if (td->td_flags & TDF_SINTR) 243 strlcat(state, "S", sizeof(state)); 244 else 245 strlcat(state, "D", sizeof(state)); 246 } 247 if (TD_IS_SWAPPED(td)) 248 strlcat(state, "W", sizeof(state)); 249 if (TD_AWAITING_INTR(td)) 250 strlcat(state, "I", sizeof(state)); 251 if (TD_IS_SUSPENDED(td)) 252 strlcat(state, "s", sizeof(state)); 253 if (state[0] != '\0') 254 break; 255 default: 256 snprintf(state, sizeof(state), "???"); 257 } 258 db_printf(" %-6.6s ", state); 259 } 260 wprefix = ' '; 261 if (TD_ON_LOCK(td)) { 262 wprefix = '*'; 263 wmesg = td->td_lockname; 264 wchan = td->td_blocked; 265 } else if (TD_ON_SLEEPQ(td)) { 266 wmesg = td->td_wmesg; 267 wchan = td->td_wchan; 268 } else if (TD_IS_RUNNING(td)) { 269 snprintf(state, sizeof(state), "CPU %d", td->td_oncpu); 270 wmesg = state; 271 wchan = NULL; 272 } else { 273 wmesg = ""; 274 wchan = NULL; 275 } 276 db_printf("%c%-8.8s ", wprefix, wmesg); 277 if (wchan == NULL) 278 #ifdef PTR64 279 db_printf("%18s ", ""); 280 #else 281 db_printf("%10s ", ""); 282 #endif 283 else 284 db_printf("%p ", wchan); 285 if (p->p_flag & P_SYSTEM) 286 db_printf("["); 287 if (td->td_name[0] != '\0') 288 db_printf("%s", td->td_name); 289 else 290 db_printf("%s", td->td_proc->p_comm); 291 if (p->p_flag & P_SYSTEM) 292 db_printf("]"); 293 db_printf("\n"); 294 } 295 296 DB_SHOW_COMMAND(thread, db_show_thread) 297 { 298 struct thread *td; 299 boolean_t comma; 300 301 /* Determine which thread to examine. */ 302 if (have_addr) 303 td = db_lookup_thread(addr, FALSE); 304 else 305 td = kdb_thread; 306 307 db_printf("Thread %d at %p:\n", td->td_tid, td); 308 db_printf(" proc (pid %d): %p ", td->td_proc->p_pid, td->td_proc); 309 db_printf(" ksegrp: %p\n", td->td_ksegrp); 310 if (td->td_name[0] != '\0') 311 db_printf(" name: %s\n", td->td_name); 312 db_printf(" flags: %#x ", td->td_flags); 313 db_printf(" pflags: %#x\n", td->td_pflags); 314 db_printf(" state: "); 315 switch (td->td_state) { 316 case TDS_INACTIVE: 317 db_printf("INACTIVE\n"); 318 break; 319 case TDS_CAN_RUN: 320 db_printf("CAN RUN\n"); 321 break; 322 case TDS_RUNQ: 323 db_printf("RUNQ\n"); 324 break; 325 case TDS_RUNNING: 326 db_printf("RUNNING (CPU %d)\n", td->td_oncpu); 327 break; 328 case TDS_INHIBITED: 329 db_printf("INHIBITED: {"); 330 comma = FALSE; 331 if (TD_IS_SLEEPING(td)) { 332 db_printf("SLEEPING"); 333 comma = TRUE; 334 } 335 if (TD_IS_SUSPENDED(td)) { 336 if (comma) 337 db_printf(", "); 338 db_printf("SUSPENDED"); 339 comma = TRUE; 340 } 341 if (TD_IS_SWAPPED(td)) { 342 if (comma) 343 db_printf(", "); 344 db_printf("SWAPPED"); 345 comma = TRUE; 346 } 347 if (TD_ON_LOCK(td)) { 348 if (comma) 349 db_printf(", "); 350 db_printf("LOCK"); 351 comma = TRUE; 352 } 353 if (TD_AWAITING_INTR(td)) { 354 if (comma) 355 db_printf(", "); 356 db_printf("IWAIT"); 357 } 358 db_printf("}\n"); 359 break; 360 default: 361 db_printf("??? (%#x)\n", td->td_state); 362 break; 363 } 364 if (TD_ON_LOCK(td)) 365 db_printf(" lock: %s turnstile: %p\n", td->td_lockname, 366 td->td_blocked); 367 if (TD_ON_SLEEPQ(td)) 368 db_printf(" wmesg: %s wchan: %p\n", td->td_wmesg, 369 td->td_wchan); 370 db_printf(" priority: %d\n", td->td_priority); 371 } 372 373 DB_SHOW_COMMAND(proc, db_show_proc) 374 { 375 struct thread *td; 376 struct proc *p; 377 int i, quit; 378 379 /* Determine which process to examine. */ 380 if (have_addr) 381 p = db_lookup_proc(addr); 382 else 383 p = kdb_thread->td_proc; 384 385 quit = 0; 386 db_setup_paging(db_simple_pager, &quit, db_lines_per_page); 387 db_printf("Process %d (%s) at %p:\n", p->p_pid, p->p_comm, p); 388 db_printf(" state: "); 389 switch (p->p_state) { 390 case PRS_NEW: 391 db_printf("NEW\n"); 392 break; 393 case PRS_NORMAL: 394 db_printf("NORMAL\n"); 395 break; 396 case PRS_ZOMBIE: 397 db_printf("ZOMBIE\n"); 398 break; 399 default: 400 db_printf("??? (%#x)\n", p->p_state); 401 } 402 if (p->p_ucred != NULL) { 403 db_printf(" uid: %d gids: ", p->p_ucred->cr_uid); 404 for (i = 0; i < p->p_ucred->cr_ngroups; i++) { 405 db_printf("%d", p->p_ucred->cr_groups[i]); 406 if (i < (p->p_ucred->cr_ngroups - 1)) 407 db_printf(", "); 408 } 409 db_printf("\n"); 410 } 411 if (p->p_pptr != NULL) 412 db_printf(" parent: pid %d at %p\n", p->p_pptr->p_pid, 413 p->p_pptr); 414 if (p->p_leader != NULL && p->p_leader != p) 415 db_printf(" leader: pid %d at %p\n", p->p_leader->p_pid, 416 p->p_leader); 417 if (p->p_sysent != NULL) 418 db_printf(" ABI: %s\n", p->p_sysent->sv_name); 419 if (p->p_args != NULL) 420 db_printf(" arguments: %.*s\n", (int)p->p_args->ar_length, 421 p->p_args->ar_args); 422 db_printf(" threads: %d\n", p->p_numthreads); 423 FOREACH_THREAD_IN_PROC(p, td) { 424 dumpthread(p, td, 1); 425 if (quit) 426 break; 427 } 428 } 429