db_ps.c revision 108338
12322Sdg/*-
22322Sdg * Copyright (c) 1993 The Regents of the University of California.
32322Sdg * All rights reserved.
42322Sdg *
52322Sdg * Redistribution and use in source and binary forms, with or without
62322Sdg * modification, are permitted provided that the following conditions
72322Sdg * are met:
82322Sdg * 1. Redistributions of source code must retain the above copyright
92322Sdg *    notice, this list of conditions and the following disclaimer.
102322Sdg * 2. Redistributions in binary form must reproduce the above copyright
112322Sdg *    notice, this list of conditions and the following disclaimer in the
122322Sdg *    documentation and/or other materials provided with the distribution.
132322Sdg * 3. All advertising materials mentioning features or use of this software
142322Sdg *    must display the following acknowledgement:
152322Sdg *	This product includes software developed by the University of
162322Sdg *	California, Berkeley and its contributors.
172322Sdg * 4. Neither the name of the University nor the names of its contributors
182322Sdg *    may be used to endorse or promote products derived from this software
192322Sdg *    without specific prior written permission.
202322Sdg *
212322Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
222322Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
232322Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
242322Sdg * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
252322Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
262322Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
272322Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
282322Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
292322Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
302322Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
312322Sdg * SUCH DAMAGE.
322322Sdg *
3350477Speter * $FreeBSD: head/sys/ddb/db_ps.c 108338 2002-12-28 01:23:07Z julian $
342322Sdg */
352322Sdg#include <sys/param.h>
362322Sdg#include <sys/systm.h>
3774914Sjhb#include <sys/lock.h>
3874914Sjhb#include <sys/mutex.h>
392322Sdg#include <sys/proc.h>
4049558Sphk#include <sys/cons.h>
41108338Sjulian#include <vm/vm.h>
42108338Sjulian#include <vm/vm_param.h>
43108338Sjulian#include <vm/pmap.h>
4412734Sbde
4512734Sbde#include <ddb/ddb.h>
46108338Sjulianstatic void
47108338Sjuliandumpthread(volatile struct proc *p, volatile struct thread *td);
4812734Sbde
492322Sdgvoid
5010349Sbdedb_ps(dummy1, dummy2, dummy3, dummy4)
5110349Sbde	db_expr_t	dummy1;
5210349Sbde	boolean_t	dummy2;
5310349Sbde	db_expr_t	dummy3;
5410349Sbde	char *		dummy4;
5510349Sbde{
562322Sdg	int np;
572322Sdg	int nl = 0;
5810128Sdg	volatile struct proc *p, *pp;
5985207Sjhb	volatile struct thread *td;
6099072Sjulian	char *state;
6110128Sdg
622322Sdg	np = nprocs;
632322Sdg
6494456Sjhb	/* sx_slock(&allproc_lock); */
6570527Sphk	if (!LIST_EMPTY(&allproc))
6670527Sphk		p = LIST_FIRST(&allproc);
6710128Sdg	else
6810128Sdg		p = &proc0;
6910128Sdg
70101784Sphk	db_printf("  pid   proc     addr    uid  ppid  pgrp  flag   stat  wmesg    wchan  cmd\n");
712322Sdg	while (--np >= 0) {
722322Sdg		/*
732322Sdg		 * XXX just take 20 for now...
742322Sdg		 */
752322Sdg		if (nl++ == 20) {
7610128Sdg			int c;
7710128Sdg
782322Sdg			db_printf("--More--");
7910128Sdg			c = cngetc();
802322Sdg			db_printf("\r");
8110128Sdg			/*
8210128Sdg			 * A whole screenfull or just one line?
8310128Sdg			 */
8410128Sdg			switch (c) {
8510128Sdg			case '\n':		/* just one line */
8630239Sbde				nl = 20;
8710128Sdg				break;
8810128Sdg			case ' ':
8910128Sdg				nl = 0;		/* another screenfull */
9010128Sdg				break;
9110128Sdg			default:		/* exit */
9210128Sdg				db_printf("\n");
9310128Sdg				return;
9410128Sdg			}
952322Sdg		}
9616381Speter		if (p == NULL) {
9716381Speter			printf("oops, ran out of processes early!\n");
9816381Speter			break;
9916381Speter		}
10094456Sjhb		/* PROC_LOCK(p); */
1012322Sdg		pp = p->p_pptr;
10210128Sdg		if (pp == NULL)
1032322Sdg			pp = p;
10410128Sdg
10599072Sjulian
10699072Sjulian		switch(p->p_state) {
10799072Sjulian		case PRS_NORMAL:
10899072Sjulian			if (P_SHOULDSTOP(p))
109101784Sphk				state = "stop";
11099072Sjulian			else
111101784Sphk				state = "norm";
11299072Sjulian			break;
11399072Sjulian		case PRS_NEW:
114101784Sphk			state = "new ";
11599072Sjulian			break;
11699072Sjulian		case PRS_ZOMBIE:
117103216Sjulian			state = "zomb";
11899072Sjulian			break;
11999072Sjulian		default:
120101784Sphk			state = "Unkn";
12199072Sjulian			break;
12299072Sjulian		}
123101784Sphk		db_printf("%5d %8p %8p %4d %5d %5d %07x %-4s",
12483383Sjhb		    p->p_pid, (volatile void *)p, (void *)p->p_uarea,
125102667Sbde		    p->p_ucred != NULL ? p->p_ucred->cr_ruid : 0, pp->p_pid,
126102667Sbde		    p->p_pgrp != NULL ? p->p_pgrp->pg_id : 0, p->p_flag,
127102667Sbde		    state);
128103216Sjulian		if (p->p_flag & P_KSES)
12983383Sjhb			db_printf("(threaded)  %s\n", p->p_comm);
130103216Sjulian		FOREACH_THREAD_IN_PROC(p, td) {
131108338Sjulian			dumpthread(p, td);
1322322Sdg		}
13394456Sjhb		/* PROC_UNLOCK(p); */
13494456Sjhb
13570527Sphk		p = LIST_NEXT(p, p_list);
13610128Sdg		if (p == NULL && np > 0)
13770527Sphk			p = LIST_FIRST(&zombproc);
1382322Sdg    	}
13994456Sjhb	/* sx_sunlock(&allproc_lock); */
1402322Sdg}
141108338Sjulianstatic void
142108338Sjuliandumpthread(volatile struct proc *p, volatile struct thread *td)
143108338Sjulian{
144108338Sjulian	if (p->p_flag & P_KSES)
145108338Sjulian		db_printf( "   thread %p ksegrp %p ", td, td->td_ksegrp);
146108338Sjulian	if (TD_ON_SLEEPQ(td)) {
147108338Sjulian		if (td->td_flags & TDF_CVWAITQ)
148108338Sjulian			db_printf("[CVQ ");
149108338Sjulian		else
150108338Sjulian			db_printf("[SLPQ ");
151108338Sjulian		db_printf(" %6s %8p]", td->td_wmesg,
152108338Sjulian		    (void *)td->td_wchan);
153108338Sjulian	}
154108338Sjulian	switch (td->td_state) {
155108338Sjulian	case TDS_INHIBITED:
156108338Sjulian		if (TD_ON_LOCK(td)) {
157108338Sjulian			db_printf("[LOCK %6s %8p]",
158108338Sjulian			    td->td_lockname,
159108338Sjulian			    (void *)td->td_blocked);
160108338Sjulian		}
161108338Sjulian		if (TD_IS_SLEEPING(td)) {
162108338Sjulian			db_printf("[SLP]");
163108338Sjulian		}
164108338Sjulian		if (TD_IS_SWAPPED(td)) {
165108338Sjulian			db_printf("[SWAP]");
166108338Sjulian		}
167108338Sjulian		if (TD_IS_SUSPENDED(td)) {
168108338Sjulian			db_printf("[SUSP]");
169108338Sjulian		}
170108338Sjulian		if (TD_AWAITING_INTR(td)) {
171108338Sjulian			db_printf("[IWAIT]");
172108338Sjulian		}
173108338Sjulian		if (TD_LENDER(td)) {
174108338Sjulian			db_printf("[LOAN]");
175108338Sjulian		}
176108338Sjulian		if (TD_IS_IDLE(td)) {
177108338Sjulian			db_printf("[IDLE]");
178108338Sjulian		}
179108338Sjulian		if (TD_IS_EXITING(td)) {
180108338Sjulian			db_printf("[EXIT]");
181108338Sjulian		}
182108338Sjulian		break;
183108338Sjulian	case TDS_CAN_RUN:
184108338Sjulian		db_printf("[Can run]");
185108338Sjulian		break;
186108338Sjulian	case TDS_RUNQ:
187108338Sjulian		db_printf("[RUNQ]");
188108338Sjulian		break;
189108338Sjulian	case TDS_RUNNING:
190108338Sjulian		db_printf("[CPU %d]", td->td_kse->ke_oncpu);
191108338Sjulian		break;
192108338Sjulian	default:
193108338Sjulian		panic("unknown thread state");
194108338Sjulian	}
195108338Sjulian	if (p->p_flag & P_KSES) {
196108338Sjulian		if (td->td_kse)
197108338Sjulian			db_printf("[kse %p]", td->td_kse);
198108338Sjulian		db_printf("\n");
199108338Sjulian	} else
200108338Sjulian		db_printf(" %s\n", p->p_comm);
201108338Sjulian}
202108338Sjulian
203108338Sjulian
204108338Sjulian#define INKERNEL(va)    (((vm_offset_t)(va)) >= USRSTACK)
205108338Sjulianvoid
206108338Sjuliandb_show_one_thread(db_expr_t addr, boolean_t have_addr,
207108338Sjulian		db_expr_t count, char *modif)
208108338Sjulian{
209108338Sjulian	struct proc *p;
210108338Sjulian	struct thread *td;
211108338Sjulian
212108338Sjulian	if (!have_addr)
213108338Sjulian		td = curthread;
214108338Sjulian	else if (!INKERNEL(addr)) {
215108338Sjulian		printf("bad thread address");
216108338Sjulian		return;
217108338Sjulian	} else
218108338Sjulian		td = (struct thread *)addr;
219108338Sjulian	/* quick sanity check */
220108338Sjulian	if ((p = td->td_proc) != td->td_ksegrp->kg_proc)
221108338Sjulian		return;
222108338Sjulian	printf("Proc %p ",p);
223108338Sjulian	dumpthread(p, td);
224108338Sjulian#ifdef	__i386__
225108338Sjulian	db_stack_thread((db_expr_t)td, 1, count, modif);
226108338Sjulian#endif
227108338Sjulian}
228