db_ps.c revision 119594
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 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/ddb/db_ps.c 119594 2003-08-30 19:06:57Z phk $");
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/lock.h>
40#include <sys/mutex.h>
41#include <sys/proc.h>
42#include <sys/cons.h>
43#include <vm/vm.h>
44#include <vm/vm_param.h>
45#include <vm/pmap.h>
46
47#include <ddb/ddb.h>
48
49static void	dumpthread(volatile struct proc *p, volatile struct thread *td);
50
51void
52db_ps(dummy1, dummy2, dummy3, dummy4)
53	db_expr_t	dummy1;
54	boolean_t	dummy2;
55	db_expr_t	dummy3;
56	char *		dummy4;
57{
58	volatile struct proc *p, *pp;
59	volatile struct thread *td;
60	char *state;
61	int np, quit;
62
63	np = nprocs;
64	quit = 0;
65
66	/* sx_slock(&allproc_lock); */
67	if (!LIST_EMPTY(&allproc))
68		p = LIST_FIRST(&allproc);
69	else
70		p = &proc0;
71
72	db_setup_paging(db_simple_pager, &quit, DB_LINES_PER_PAGE);
73	db_printf("  pid   proc     uarea   uid  ppid  pgrp  flag   stat  wmesg    wchan  cmd\n");
74	while (--np >= 0 && !quit) {
75		if (p == NULL) {
76			printf("oops, ran out of processes early!\n");
77			break;
78		}
79		/* PROC_LOCK(p); */
80		pp = p->p_pptr;
81		if (pp == NULL)
82			pp = p;
83
84
85		switch(p->p_state) {
86		case PRS_NORMAL:
87			if (P_SHOULDSTOP(p))
88				state = "stop";
89			else
90				state = "";
91			break;
92		case PRS_NEW:
93			state = "new ";
94			break;
95		case PRS_ZOMBIE:
96			state = "zomb";
97			break;
98		default:
99			state = "Unkn";
100			break;
101		}
102		db_printf("%5d %8p %8p %4d %5d %5d %07x %s",
103		    p->p_pid, (volatile void *)p, (void *)p->p_uarea,
104		    p->p_ucred != NULL ? p->p_ucred->cr_ruid : 0, pp->p_pid,
105		    p->p_pgrp != NULL ? p->p_pgrp->pg_id : 0, p->p_flag,
106		    state);
107		if (p->p_flag & P_SA)
108			db_printf("(threaded)  %s\n", p->p_comm);
109		FOREACH_THREAD_IN_PROC(p, td) {
110			dumpthread(p, td);
111			if (quit)
112				break;
113		}
114		/* PROC_UNLOCK(p); */
115
116		p = LIST_NEXT(p, p_list);
117		if (p == NULL && np > 0)
118			p = LIST_FIRST(&zombproc);
119    	}
120	/* sx_sunlock(&allproc_lock); */
121}
122
123static void
124dumpthread(volatile struct proc *p, volatile struct thread *td)
125{
126
127	if (p->p_flag & P_SA)
128		db_printf( "   thread %p ksegrp %p ", td, td->td_ksegrp);
129	if (TD_ON_SLEEPQ(td)) {
130		if (td->td_flags & TDF_CVWAITQ)
131			if (TD_IS_SLEEPING(td))
132				db_printf("[CV]");
133			else
134				db_printf("[CVQ");
135		else
136			if (TD_IS_SLEEPING(td))
137				db_printf("[SLP]");
138			else
139				db_printf("[SLPQ");
140		db_printf("%s %p]", td->td_wmesg,
141		    (void *)td->td_wchan);
142	}
143	switch (td->td_state) {
144	case TDS_INHIBITED:
145		if (TD_ON_LOCK(td)) {
146			db_printf("[LOCK %6s %8p]",
147			    td->td_lockname,
148			    (void *)td->td_blocked);
149		}
150#if 0 /* covered above */
151		if (TD_IS_SLEEPING(td)) {
152			db_printf("[SLP]");
153		}
154#endif
155		if (TD_IS_SWAPPED(td)) {
156			db_printf("[SWAP]");
157		}
158		if (TD_IS_SUSPENDED(td)) {
159			db_printf("[SUSP]");
160		}
161		if (TD_AWAITING_INTR(td)) {
162			db_printf("[IWAIT]");
163		}
164		break;
165	case TDS_CAN_RUN:
166		db_printf("[Can run]");
167		break;
168	case TDS_RUNQ:
169		db_printf("[RUNQ]");
170		break;
171	case TDS_RUNNING:
172		db_printf("[CPU %d]", td->td_oncpu);
173		break;
174	case TDS_INACTIVE:
175		db_printf("[INACTIVE]");
176		break;
177	default:
178		db_printf("[UNK: %#x]", td->td_state);
179	}
180	if (p->p_flag & P_SA) {
181		if (td->td_kse)
182			db_printf("[kse %p]", td->td_kse);
183		db_printf("\n");
184	} else
185		db_printf(" %s\n", p->p_comm);
186}
187
188
189#define INKERNEL(va)    (((vm_offset_t)(va)) >= USRSTACK)
190void
191db_show_one_thread(db_expr_t addr, boolean_t have_addr,
192		db_expr_t count, char *modif)
193{
194	struct proc *p;
195	struct thread *td;
196
197	if (!have_addr)
198		td = curthread;
199	else if (!INKERNEL(addr)) {
200		printf("bad thread address");
201		return;
202	} else
203		td = (struct thread *)addr;
204	/* quick sanity check */
205	if ((p = td->td_proc) != td->td_ksegrp->kg_proc)
206		return;
207	printf("Proc %p ",p);
208	dumpthread(p, td);
209#ifdef	__i386__
210	db_stack_thread((db_expr_t)td, 1, count, modif);
211#endif
212}
213