1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1993 The Regents of the University of California. 5 * 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 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_kstack_pages.h" 36 37 #include <sys/param.h> 38 #include <sys/cons.h> 39 #include <sys/jail.h> 40 #include <sys/kdb.h> 41 #include <sys/kernel.h> 42 #include <sys/proc.h> 43 #include <sys/sysent.h> 44 #include <sys/systm.h> 45 #include <sys/_kstack_cache.h> 46 #include <vm/vm.h> 47 #include <vm/vm_param.h> 48 #include <vm/pmap.h> 49 50 #include <ddb/ddb.h> 51 52 static void dumpthread(volatile struct proc *p, volatile struct thread *td, 53 int all); 54 /* 55 * At least one non-optional show-command must be implemented using 56 * DB_SHOW_ALL_COMMAND() so that db_show_all_cmd_set gets created. 57 * Here is one. 58 */ 59 DB_SHOW_ALL_COMMAND(procs, db_procs_cmd) 60 { 61 db_ps(addr, have_addr, count, modif); 62 } 63 64 /* 65 * Layout: 66 * - column counts 67 * - header 68 * - single-threaded process 69 * - multi-threaded process 70 * - thread in a MT process 71 * 72 * 1 2 3 4 5 6 7 73 * 1234567890123456789012345678901234567890123456789012345678901234567890 74 * pid ppid pgrp uid state wmesg wchan cmd 75 * <pid> <ppi> <pgi> <uid> <stat> <wmesg> <wchan > <name> 76 * <pid> <ppi> <pgi> <uid> <stat> (threaded) <command> 77 * <tid > <stat> <wmesg> <wchan > <name> 78 * 79 * For machines with 64-bit pointers, we expand the wchan field 8 more 80 * characters. 81 */ 82 void 83 db_ps(db_expr_t addr, bool hasaddr, db_expr_t count, char *modif) 84 { 85 volatile struct proc *p, *pp; 86 volatile struct thread *td; 87 struct ucred *cred; 88 struct pgrp *pgrp; 89 char state[9]; 90 int np, rflag, sflag, dflag, lflag, wflag; 91 92 np = nprocs; 93 94 if (!LIST_EMPTY(&allproc)) 95 p = LIST_FIRST(&allproc); 96 else 97 p = &proc0; 98 99 #ifdef __LP64__ 100 db_printf(" pid ppid pgrp uid state wmesg wchan cmd\n"); 101 #else 102 db_printf(" pid ppid pgrp uid state wmesg wchan cmd\n"); 103 #endif 104 while (--np >= 0 && !db_pager_quit) { 105 if (p == NULL) { 106 db_printf("oops, ran out of processes early!\n"); 107 break; 108 } 109 pp = p->p_pptr; 110 if (pp == NULL) 111 pp = p; 112 113 cred = p->p_ucred; 114 pgrp = p->p_pgrp; 115 db_printf("%5d %5d %5d %5d ", p->p_pid, pp->p_pid, 116 pgrp != NULL ? pgrp->pg_id : 0, 117 cred != NULL ? cred->cr_ruid : 0); 118 119 /* Determine our primary process state. */ 120 switch (p->p_state) { 121 case PRS_NORMAL: 122 if (P_SHOULDSTOP(p)) 123 state[0] = 'T'; 124 else { 125 /* 126 * One of D, L, R, S, W. For a 127 * multithreaded process we will use 128 * the state of the thread with the 129 * highest precedence. The 130 * precendence order from high to low 131 * is R, L, D, S, W. If no thread is 132 * in a sane state we use '?' for our 133 * primary state. 134 */ 135 rflag = sflag = dflag = lflag = wflag = 0; 136 FOREACH_THREAD_IN_PROC(p, td) { 137 if (td->td_state == TDS_RUNNING || 138 td->td_state == TDS_RUNQ || 139 td->td_state == TDS_CAN_RUN) 140 rflag++; 141 if (TD_ON_LOCK(td)) 142 lflag++; 143 if (TD_IS_SLEEPING(td)) { 144 if (!(td->td_flags & TDF_SINTR)) 145 dflag++; 146 else 147 sflag++; 148 } 149 if (TD_AWAITING_INTR(td)) 150 wflag++; 151 } 152 if (rflag) 153 state[0] = 'R'; 154 else if (lflag) 155 state[0] = 'L'; 156 else if (dflag) 157 state[0] = 'D'; 158 else if (sflag) 159 state[0] = 'S'; 160 else if (wflag) 161 state[0] = 'W'; 162 else 163 state[0] = '?'; 164 } 165 break; 166 case PRS_NEW: 167 state[0] = 'N'; 168 break; 169 case PRS_ZOMBIE: 170 state[0] = 'Z'; 171 break; 172 default: 173 state[0] = 'U'; 174 break; 175 } 176 state[1] = '\0'; 177 178 /* Additional process state flags. */ 179 if (!(p->p_flag & P_INMEM)) 180 strlcat(state, "W", sizeof(state)); 181 if (p->p_flag & P_TRACED) 182 strlcat(state, "X", sizeof(state)); 183 if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE) 184 strlcat(state, "E", sizeof(state)); 185 if (p->p_flag & P_PPWAIT) 186 strlcat(state, "V", sizeof(state)); 187 if (p->p_flag & P_SYSTEM || p->p_lock > 0) 188 strlcat(state, "L", sizeof(state)); 189 if (p->p_pgrp != NULL && p->p_session != NULL && 190 SESS_LEADER(p)) 191 strlcat(state, "s", sizeof(state)); 192 /* Cheated here and didn't compare pgid's. */ 193 if (p->p_flag & P_CONTROLT) 194 strlcat(state, "+", sizeof(state)); 195 if (cred != NULL && jailed(cred)) 196 strlcat(state, "J", sizeof(state)); 197 db_printf(" %-6.6s ", state); 198 if (p->p_flag & P_HADTHREADS) { 199 #ifdef __LP64__ 200 db_printf(" (threaded) "); 201 #else 202 db_printf(" (threaded) "); 203 #endif 204 if (p->p_flag & P_SYSTEM) 205 db_printf("["); 206 db_printf("%s", p->p_comm); 207 if (p->p_flag & P_SYSTEM) 208 db_printf("]"); 209 db_printf("\n"); 210 } 211 FOREACH_THREAD_IN_PROC(p, td) { 212 dumpthread(p, td, p->p_flag & P_HADTHREADS); 213 if (db_pager_quit) 214 break; 215 } 216 217 p = LIST_NEXT(p, p_list); 218 if (p == NULL && np > 0) 219 p = LIST_FIRST(&zombproc); 220 } 221 } 222 223 static void 224 dumpthread(volatile struct proc *p, volatile struct thread *td, int all) 225 { 226 char state[9], wprefix; 227 const char *wmesg; 228 void *wchan; 229 230 if (all) { 231 db_printf("%6d ", td->td_tid); 232 switch (td->td_state) { 233 case TDS_RUNNING: 234 snprintf(state, sizeof(state), "Run"); 235 break; 236 case TDS_RUNQ: 237 snprintf(state, sizeof(state), "RunQ"); 238 break; 239 case TDS_CAN_RUN: 240 snprintf(state, sizeof(state), "CanRun"); 241 break; 242 case TDS_INACTIVE: 243 snprintf(state, sizeof(state), "Inactv"); 244 break; 245 case TDS_INHIBITED: 246 state[0] = '\0'; 247 if (TD_ON_LOCK(td)) 248 strlcat(state, "L", sizeof(state)); 249 if (TD_IS_SLEEPING(td)) { 250 if (td->td_flags & TDF_SINTR) 251 strlcat(state, "S", sizeof(state)); 252 else 253 strlcat(state, "D", sizeof(state)); 254 } 255 if (TD_IS_SWAPPED(td)) 256 strlcat(state, "W", sizeof(state)); 257 if (TD_AWAITING_INTR(td)) 258 strlcat(state, "I", sizeof(state)); 259 if (TD_IS_SUSPENDED(td)) 260 strlcat(state, "s", sizeof(state)); 261 if (state[0] != '\0') 262 break; 263 default: 264 snprintf(state, sizeof(state), "???"); 265 } 266 db_printf(" %-6.6s ", state); 267 } 268 wprefix = ' '; 269 if (TD_ON_LOCK(td)) { 270 wprefix = '*'; 271 wmesg = td->td_lockname; 272 wchan = td->td_blocked; 273 } else if (TD_ON_SLEEPQ(td)) { 274 wmesg = td->td_wmesg; 275 wchan = td->td_wchan; 276 } else if (TD_IS_RUNNING(td)) { 277 snprintf(state, sizeof(state), "CPU %d", td->td_oncpu); 278 wmesg = state; 279 wchan = NULL; 280 } else { 281 wmesg = ""; 282 wchan = NULL; 283 } 284 db_printf("%c%-7.7s ", wprefix, wmesg); 285 if (wchan == NULL) 286 #ifdef __LP64__ 287 db_printf("%18s ", ""); 288 #else 289 db_printf("%10s ", ""); 290 #endif 291 else 292 db_printf("%p ", wchan); 293 if (p->p_flag & P_SYSTEM) 294 db_printf("["); 295 if (td->td_name[0] != '\0') 296 db_printf("%s", td->td_name); 297 else 298 db_printf("%s", td->td_proc->p_comm); 299 if (p->p_flag & P_SYSTEM) 300 db_printf("]"); 301 db_printf("\n"); 302 } 303 304 DB_SHOW_COMMAND(thread, db_show_thread) 305 { 306 struct thread *td; 307 struct lock_object *lock; 308 bool comma; 309 int delta; 310 311 /* Determine which thread to examine. */ 312 if (have_addr) 313 td = db_lookup_thread(addr, false); 314 else 315 td = kdb_thread; 316 lock = (struct lock_object *)td->td_lock; 317 318 db_printf("Thread %d at %p:\n", td->td_tid, td); 319 db_printf(" proc (pid %d): %p\n", td->td_proc->p_pid, td->td_proc); 320 if (td->td_name[0] != '\0') 321 db_printf(" name: %s\n", td->td_name); 322 db_printf(" stack: %p-%p\n", (void *)td->td_kstack, 323 (void *)(td->td_kstack + td->td_kstack_pages * PAGE_SIZE - 1)); 324 db_printf(" flags: %#x ", td->td_flags); 325 db_printf(" pflags: %#x\n", td->td_pflags); 326 db_printf(" state: "); 327 switch (td->td_state) { 328 case TDS_INACTIVE: 329 db_printf("INACTIVE\n"); 330 break; 331 case TDS_CAN_RUN: 332 db_printf("CAN RUN\n"); 333 break; 334 case TDS_RUNQ: 335 db_printf("RUNQ\n"); 336 break; 337 case TDS_RUNNING: 338 db_printf("RUNNING (CPU %d)\n", td->td_oncpu); 339 break; 340 case TDS_INHIBITED: 341 db_printf("INHIBITED: {"); 342 comma = false; 343 if (TD_IS_SLEEPING(td)) { 344 db_printf("SLEEPING"); 345 comma = true; 346 } 347 if (TD_IS_SUSPENDED(td)) { 348 if (comma) 349 db_printf(", "); 350 db_printf("SUSPENDED"); 351 comma = true; 352 } 353 if (TD_IS_SWAPPED(td)) { 354 if (comma) 355 db_printf(", "); 356 db_printf("SWAPPED"); 357 comma = true; 358 } 359 if (TD_ON_LOCK(td)) { 360 if (comma) 361 db_printf(", "); 362 db_printf("LOCK"); 363 comma = true; 364 } 365 if (TD_AWAITING_INTR(td)) { 366 if (comma) 367 db_printf(", "); 368 db_printf("IWAIT"); 369 } 370 db_printf("}\n"); 371 break; 372 default: 373 db_printf("??? (%#x)\n", td->td_state); 374 break; 375 } 376 if (TD_ON_LOCK(td)) 377 db_printf(" lock: %s turnstile: %p\n", td->td_lockname, 378 td->td_blocked); 379 if (TD_ON_SLEEPQ(td)) 380 db_printf( 381 " wmesg: %s wchan: %p sleeptimo %lx. %jx (curr %lx. %jx)\n", 382 td->td_wmesg, td->td_wchan, 383 (long)sbttobt(td->td_sleeptimo).sec, 384 (uintmax_t)sbttobt(td->td_sleeptimo).frac, 385 (long)sbttobt(sbinuptime()).sec, 386 (uintmax_t)sbttobt(sbinuptime()).frac); 387 db_printf(" priority: %d\n", td->td_priority); 388 db_printf(" container lock: %s (%p)\n", lock->lo_name, lock); 389 if (td->td_swvoltick != 0) { 390 delta = (u_int)ticks - (u_int)td->td_swvoltick; 391 db_printf(" last voluntary switch: %d ms ago\n", 392 1000 * delta / hz); 393 } 394 if (td->td_swinvoltick != 0) { 395 delta = (u_int)ticks - (u_int)td->td_swinvoltick; 396 db_printf(" last involuntary switch: %d ms ago\n", 397 1000 * delta / hz); 398 } 399 } 400 401 DB_SHOW_COMMAND(proc, db_show_proc) 402 { 403 struct thread *td; 404 struct proc *p; 405 int i; 406 407 /* Determine which process to examine. */ 408 if (have_addr) 409 p = db_lookup_proc(addr); 410 else 411 p = kdb_thread->td_proc; 412 413 db_printf("Process %d (%s) at %p:\n", p->p_pid, p->p_comm, p); 414 db_printf(" state: "); 415 switch (p->p_state) { 416 case PRS_NEW: 417 db_printf("NEW\n"); 418 break; 419 case PRS_NORMAL: 420 db_printf("NORMAL\n"); 421 break; 422 case PRS_ZOMBIE: 423 db_printf("ZOMBIE\n"); 424 break; 425 default: 426 db_printf("??? (%#x)\n", p->p_state); 427 } 428 if (p->p_ucred != NULL) { 429 db_printf(" uid: %d gids: ", p->p_ucred->cr_uid); 430 for (i = 0; i < p->p_ucred->cr_ngroups; i++) { 431 db_printf("%d", p->p_ucred->cr_groups[i]); 432 if (i < (p->p_ucred->cr_ngroups - 1)) 433 db_printf(", "); 434 } 435 db_printf("\n"); 436 } 437 if (p->p_pptr != NULL) 438 db_printf(" parent: pid %d at %p\n", p->p_pptr->p_pid, 439 p->p_pptr); 440 if (p->p_leader != NULL && p->p_leader != p) 441 db_printf(" leader: pid %d at %p\n", p->p_leader->p_pid, 442 p->p_leader); 443 if (p->p_sysent != NULL) 444 db_printf(" ABI: %s\n", p->p_sysent->sv_name); 445 if (p->p_args != NULL) { 446 db_printf(" arguments: "); 447 for (i = 0; i < (int)p->p_args->ar_length; i++) { 448 if (p->p_args->ar_args[i] == '\0') 449 db_printf(" "); 450 else 451 db_printf("%c", p->p_args->ar_args[i]); 452 } 453 db_printf("\n"); 454 } 455 db_printf(" threads: %d\n", p->p_numthreads); 456 FOREACH_THREAD_IN_PROC(p, td) { 457 dumpthread(p, td, 1); 458 if (db_pager_quit) 459 break; 460 } 461 } 462 463 void 464 db_findstack_cmd(db_expr_t addr, bool have_addr, db_expr_t dummy3 __unused, 465 char *dummy4 __unused) 466 { 467 struct proc *p; 468 struct thread *td; 469 struct kstack_cache_entry *ks_ce; 470 vm_offset_t saddr; 471 472 if (have_addr) 473 saddr = addr; 474 else { 475 db_printf("Usage: findstack <address>\n"); 476 return; 477 } 478 479 FOREACH_PROC_IN_SYSTEM(p) { 480 FOREACH_THREAD_IN_PROC(p, td) { 481 if (td->td_kstack <= saddr && saddr < td->td_kstack + 482 PAGE_SIZE * td->td_kstack_pages) { 483 db_printf("Thread %p\n", td); 484 return; 485 } 486 } 487 } 488 489 for (ks_ce = kstack_cache; ks_ce != NULL; 490 ks_ce = ks_ce->next_ks_entry) { 491 if ((vm_offset_t)ks_ce <= saddr && saddr < (vm_offset_t)ks_ce + 492 PAGE_SIZE * kstack_pages) { 493 db_printf("Cached stack %p\n", ks_ce); 494 return; 495 } 496 } 497 } 498