Home | History | Annotate | Line # | Download | only in ddb
db_proc.c revision 1.8.6.2
      1  1.8.6.2        ad /*	$NetBSD: db_proc.c,v 1.8.6.2 2020/02/29 20:21:01 ad Exp $	*/
      2      1.1        ad 
      3      1.1        ad /*-
      4  1.8.6.2        ad  * Copyright (c) 2009, 2020 The NetBSD Foundation, Inc.
      5      1.1        ad  * All rights reserved.
      6      1.1        ad  *
      7      1.1        ad  * This code is derived from software contributed to The NetBSD Foundation
      8      1.1        ad  * by Andrew Doran.
      9      1.1        ad  *
     10      1.1        ad  * Redistribution and use in source and binary forms, with or without
     11      1.1        ad  * modification, are permitted provided that the following conditions
     12      1.1        ad  * are met:
     13      1.1        ad  * 1. Redistributions of source code must retain the above copyright
     14      1.1        ad  *    notice, this list of conditions and the following disclaimer.
     15      1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     17      1.1        ad  *    documentation and/or other materials provided with the distribution.
     18      1.1        ad  *
     19      1.1        ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20      1.1        ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21      1.1        ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22      1.1        ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23      1.1        ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24      1.1        ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25      1.1        ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26      1.1        ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27      1.1        ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28      1.1        ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29      1.1        ad  * POSSIBILITY OF SUCH DAMAGE.
     30      1.1        ad  */
     31      1.1        ad 
     32      1.1        ad /*
     33      1.1        ad  * Copyright (c) 1982, 1986, 1989, 1991, 1993
     34      1.1        ad  *	The Regents of the University of California.  All rights reserved.
     35      1.1        ad  *
     36      1.1        ad  * Redistribution and use in source and binary forms, with or without
     37      1.1        ad  * modification, are permitted provided that the following conditions
     38      1.1        ad  * are met:
     39      1.1        ad  * 1. Redistributions of source code must retain the above copyright
     40      1.1        ad  *    notice, this list of conditions and the following disclaimer.
     41      1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     42      1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     43      1.1        ad  *    documentation and/or other materials provided with the distribution.
     44      1.1        ad  * 3. Neither the name of the University nor the names of its contributors
     45      1.1        ad  *    may be used to endorse or promote products derived from this software
     46      1.1        ad  *    without specific prior written permission.
     47      1.1        ad  *
     48      1.1        ad  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     49      1.1        ad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     50      1.1        ad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     51      1.1        ad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     52      1.1        ad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     53      1.1        ad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     54      1.1        ad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     55      1.1        ad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     56      1.1        ad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     57      1.1        ad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     58      1.1        ad  * SUCH DAMAGE.
     59      1.1        ad  *
     60      1.1        ad  *	from: kern_proc.c	8.4 (Berkeley) 1/4/94
     61      1.1        ad  */
     62      1.1        ad 
     63      1.1        ad #include <sys/cdefs.h>
     64  1.8.6.2        ad __KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.8.6.2 2020/02/29 20:21:01 ad Exp $");
     65      1.3       mrg 
     66      1.3       mrg #ifndef _KERNEL
     67      1.3       mrg #include <stdbool.h>
     68      1.3       mrg #endif
     69      1.1        ad 
     70      1.1        ad #include <sys/param.h>
     71      1.1        ad #include <sys/cpu.h>
     72      1.1        ad #include <sys/proc.h>
     73      1.3       mrg #ifdef _KERNEL	/* XXX */
     74      1.1        ad #include <sys/kauth.h>
     75      1.3       mrg #endif
     76      1.1        ad 
     77      1.2       mrg #include <ddb/ddb.h>
     78      1.2       mrg 
     79      1.1        ad proc_t *
     80      1.1        ad db_proc_first(void)
     81      1.1        ad {
     82      1.1        ad 
     83      1.1        ad 	return db_read_ptr("allproc");
     84      1.1        ad }
     85      1.1        ad 
     86      1.1        ad proc_t *
     87      1.1        ad db_proc_next(proc_t *p)
     88      1.1        ad {
     89      1.1        ad 
     90      1.1        ad 	db_read_bytes((db_addr_t)&p->p_list.le_next, sizeof(p), (char *)&p);
     91      1.1        ad 	return p;
     92      1.1        ad }
     93      1.1        ad 
     94      1.1        ad proc_t *
     95      1.1        ad db_proc_find(pid_t pid)
     96      1.1        ad {
     97      1.1        ad 	proc_t *p;
     98      1.1        ad 	pid_t tp;
     99      1.1        ad 
    100      1.1        ad 	for (p = db_proc_first(); p != NULL; p = db_proc_next(p)) {
    101      1.1        ad 		db_read_bytes((db_addr_t)&p->p_pid, sizeof(tp),
    102      1.1        ad 		    (char *)&tp);
    103      1.1        ad 		if (tp == pid) {
    104      1.1        ad 			return p;
    105      1.1        ad 		}
    106      1.1        ad 	}
    107      1.1        ad 	return NULL;
    108      1.1        ad }
    109      1.1        ad 
    110      1.7      maxv static void
    111      1.7      maxv db_read_string(const char *src, size_t len, char *dst)
    112      1.7      maxv {
    113      1.7      maxv 	size_t i;
    114      1.7      maxv 
    115      1.7      maxv 	for (i = 0; i < len; i++) {
    116      1.7      maxv 		db_read_bytes((db_addr_t)&src[i], 1, &dst[i]);
    117      1.8      maxv 		if (dst[i] == '\0')
    118      1.7      maxv 			break;
    119      1.7      maxv 	}
    120      1.7      maxv }
    121      1.7      maxv 
    122      1.1        ad void
    123      1.1        ad db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count,
    124      1.1        ad 		  const char *modif)
    125      1.1        ad {
    126      1.1        ad 	static struct pgrp pgrp;
    127      1.1        ad 	static proc_t p;
    128      1.1        ad 	static lwp_t l;
    129      1.1        ad 	const char *mode, *ename;
    130      1.1        ad 	proc_t *pp;
    131      1.1        ad 	lwp_t *lp;
    132      1.1        ad 	char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
    133      1.1        ad 	bool run;
    134      1.1        ad 	int cpuno;
    135      1.1        ad 
    136      1.1        ad 	if (modif[0] == 0)
    137      1.1        ad 		mode = "l";			/* default == lwp mode */
    138      1.1        ad 	else
    139      1.1        ad 		mode = strchr("mawln", modif[0]);
    140      1.1        ad 
    141      1.1        ad 	if (mode == NULL || *mode == 'm') {
    142      1.1        ad 		db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n");
    143      1.1        ad 		db_printf("\t/a == show process address info\n");
    144      1.4  christos 		db_printf("\t/l == show LWP info [default]\n");
    145      1.4  christos 		db_printf("\t/n == show normal process info\n");
    146      1.1        ad 		db_printf("\t/w == show process wait/emul info\n");
    147      1.1        ad 		return;
    148      1.1        ad 	}
    149      1.1        ad 
    150      1.1        ad 	switch (*mode) {
    151      1.1        ad 	case 'a':
    152      1.1        ad 		db_printf("PID  %10s %18s %18s %18s\n",
    153      1.1        ad 		    "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP");
    154      1.1        ad 		break;
    155      1.1        ad 	case 'l':
    156      1.1        ad 		db_printf("PID   %4s S %3s %9s %18s %18s %-8s\n",
    157      1.1        ad 		    "LID", "CPU", "FLAGS", "STRUCT LWP *", "NAME", "WAIT");
    158      1.1        ad 		break;
    159      1.1        ad 	case 'n':
    160      1.1        ad 		db_printf("PID  %8s %8s %10s S %7s %4s %16s %7s\n",
    161      1.1        ad 		    "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT");
    162      1.1        ad 		break;
    163      1.1        ad 	case 'w':
    164      1.1        ad 		db_printf("PID  %4s %16s %8s %4s %-12s%s\n",
    165      1.1        ad 		    "LID", "COMMAND", "EMUL", "PRI", "WAIT-MSG",
    166      1.1        ad 		    "WAIT-CHANNEL");
    167      1.1        ad 		break;
    168      1.1        ad 	}
    169      1.1        ad 
    170      1.1        ad 	for (pp = db_proc_first(); pp != NULL; pp = db_proc_next(pp)) {
    171      1.1        ad 		db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
    172      1.1        ad 		if (p.p_stat == 0) {
    173      1.1        ad 			continue;
    174      1.1        ad 		}
    175      1.1        ad 		lp = p.p_lwps.lh_first;
    176      1.1        ad 		if (lp != NULL) {
    177      1.1        ad 			db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
    178      1.1        ad 		}
    179      1.1        ad 		db_printf("%-5d", p.p_pid);
    180      1.1        ad 
    181      1.1        ad 		switch (*mode) {
    182      1.1        ad 		case 'a':
    183      1.1        ad 			db_printf("%10.10s %18lx %18lx %18lx\n",
    184      1.1        ad 			    p.p_comm, (long)pp,
    185      1.1        ad 			    (long)(lp != NULL ? l.l_addr : 0),
    186      1.1        ad 			    (long)p.p_vmspace);
    187      1.1        ad 			break;
    188      1.1        ad 		case 'l':
    189      1.1        ad 			 while (lp != NULL) {
    190      1.1        ad 			 	if (l.l_name != NULL) {
    191      1.7      maxv 					db_read_string(l.l_name,
    192      1.1        ad 					    MAXCOMLEN, db_nbuf);
    193      1.7      maxv 					db_nbuf[MAXCOMLEN] = '\0';
    194      1.1        ad 				} else {
    195      1.1        ad 					strlcpy(db_nbuf, p.p_comm,
    196      1.1        ad 					    sizeof(db_nbuf));
    197      1.1        ad 				}
    198      1.1        ad 				run = (l.l_stat == LSONPROC ||
    199  1.8.6.2        ad 				    (l.l_pflag & LP_RUNNING) != 0);
    200      1.1        ad 				if (l.l_cpu != NULL) {
    201      1.1        ad 					db_read_bytes((db_addr_t)
    202      1.1        ad 					    &l.l_cpu->ci_data.cpu_index,
    203      1.1        ad 					    sizeof(cpuno), (char *)&cpuno);
    204      1.1        ad 				} else
    205      1.1        ad 					cpuno = -1;
    206      1.1        ad 				if (l.l_wchan && l.l_wmesg) {
    207      1.7      maxv 					db_read_string(l.l_wmesg,
    208      1.7      maxv 					    sizeof(wbuf), wbuf);
    209      1.7      maxv 					wbuf[MAXCOMLEN] = '\0';
    210      1.1        ad 				} else {
    211      1.1        ad 					wbuf[0] = '\0';
    212      1.1        ad 				}
    213      1.1        ad 				db_printf("%c%4d %d %3d %9x %18lx %18s %-8s\n",
    214      1.1        ad 				    (run ? '>' : ' '), l.l_lid,
    215      1.1        ad 				    l.l_stat, cpuno, l.l_flag, (long)lp,
    216      1.1        ad 				    db_nbuf, wbuf);
    217      1.1        ad 				lp = LIST_NEXT((&l), l_sibling);
    218      1.1        ad 				if (lp != NULL) {
    219      1.1        ad 					db_printf("%-5d", p.p_pid);
    220      1.1        ad 					db_read_bytes((db_addr_t)lp, sizeof(l),
    221      1.1        ad 					    (char *)&l);
    222      1.1        ad 				}
    223      1.1        ad 			}
    224      1.1        ad 			break;
    225      1.1        ad 		case 'n':
    226      1.1        ad 			db_read_bytes((db_addr_t)p.p_pgrp, sizeof(pgrp),
    227      1.1        ad 			    (char *)&pgrp);
    228      1.1        ad 			if (lp != NULL && l.l_wchan && l.l_wmesg) {
    229      1.7      maxv 				db_read_string(l.l_wmesg,
    230      1.7      maxv 				    sizeof(wbuf), wbuf);
    231      1.7      maxv 				wbuf[MAXCOMLEN] = '\0';
    232      1.1        ad 			} else {
    233      1.1        ad 				wbuf[0] = '\0';
    234      1.1        ad 			}
    235      1.1        ad 			db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n",
    236  1.8.6.2        ad 			    p.p_pptr != NULL ? p.p_pptr->p_pid : -1, pgrp.pg_id,
    237      1.1        ad #ifdef _KERNEL
    238      1.1        ad 			    kauth_cred_getuid(p.p_cred),
    239      1.1        ad #else
    240      1.1        ad 			    /* XXX CRASH(8) */ 666,
    241      1.1        ad #endif
    242      1.1        ad 			    p.p_stat, p.p_flag,
    243      1.1        ad 			    p.p_nlwps, p.p_comm,
    244      1.1        ad 			    (p.p_nlwps != 1) ? "*" : wbuf);
    245      1.1        ad 			break;
    246      1.1        ad 
    247      1.1        ad 		case 'w':
    248      1.1        ad 			 while (lp != NULL) {
    249      1.1        ad 				if (l.l_wchan && l.l_wmesg) {
    250      1.7      maxv 					db_read_string(l.l_wmesg,
    251      1.7      maxv 					    sizeof(wbuf), wbuf);
    252      1.7      maxv 					wbuf[MAXCOMLEN] = '\0';
    253      1.1        ad 				} else {
    254      1.1        ad 					wbuf[0] = '\0';
    255      1.1        ad 				}
    256      1.6       jym 				run = (l.l_stat == LSONPROC ||
    257  1.8.6.2        ad 				    (l.l_pflag & LP_RUNNING) != 0);
    258      1.1        ad 				db_read_bytes((db_addr_t)&p.p_emul->e_name,
    259      1.1        ad 				    sizeof(ename), (char *)&ename);
    260      1.7      maxv 
    261      1.7      maxv 				db_read_string(ename, sizeof(db_nbuf), db_nbuf);
    262      1.7      maxv 				db_nbuf[MAXCOMLEN] = '\0';
    263      1.7      maxv 
    264      1.1        ad 				db_printf(
    265      1.6       jym 				    "%c%4d %16s %8s %4d %-12s %-18lx\n",
    266      1.6       jym 				    (run ? '>' : ' '), l.l_lid,
    267      1.6       jym 				    p.p_comm, db_nbuf,
    268      1.1        ad 				    l.l_priority, wbuf, (long)l.l_wchan);
    269      1.1        ad 				lp = LIST_NEXT((&l), l_sibling);
    270      1.1        ad 				if (lp != NULL) {
    271      1.1        ad 					db_printf("%-5d", p.p_pid);
    272      1.1        ad 					db_read_bytes((db_addr_t)lp, sizeof(l),
    273      1.1        ad 					    (char *)&l);
    274      1.1        ad 				}
    275      1.1        ad 			}
    276      1.1        ad 			break;
    277      1.1        ad 		}
    278      1.1        ad 	}
    279      1.1        ad }
    280      1.1        ad 
    281      1.4  christos void
    282      1.4  christos db_show_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
    283      1.4  christos {
    284      1.4  christos 	static proc_t p;
    285      1.4  christos 	static lwp_t l;
    286      1.4  christos 	const char *mode;
    287      1.4  christos 	proc_t *pp;
    288      1.4  christos 	lwp_t *lp;
    289      1.4  christos 	char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
    290      1.4  christos 	bool run;
    291      1.4  christos 	int cpuno;
    292      1.4  christos 
    293      1.4  christos 	if (modif[0] == 0)
    294      1.4  christos 		mode = "p";			/* default == by pid */
    295      1.4  christos 	else
    296      1.4  christos 		mode = strchr("ap", modif[0]);
    297      1.4  christos 
    298      1.4  christos 	if (mode == NULL || !haddr) {
    299      1.4  christos 		db_printf("usage: show proc [/a] [/p] address|pid\n");
    300      1.4  christos 		db_printf("\t/a == argument is an address of any lwp\n");
    301      1.4  christos 		db_printf("\t/p == argument is a pid [default]\n");
    302      1.4  christos 		return;
    303      1.4  christos 	}
    304      1.4  christos 
    305      1.4  christos 	switch (*mode) {
    306      1.4  christos 	case 'a':
    307      1.5  nakayama 		lp = (lwp_t *)(uintptr_t)addr;
    308      1.4  christos 		db_printf("lwp_t %lx\n", (long)lp);
    309      1.4  christos 		db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
    310      1.4  christos 		pp = l.l_proc;
    311      1.4  christos 		break;
    312      1.4  christos 	default:
    313      1.4  christos 	case 'p':
    314      1.4  christos 		pp = db_proc_find((pid_t)addr);
    315      1.4  christos 		lp = NULL;
    316      1.4  christos 		break;
    317      1.4  christos 	}
    318      1.4  christos 
    319      1.4  christos 	if (pp == NULL) {
    320      1.4  christos 		db_printf("bad address\n");
    321      1.4  christos 		return;
    322      1.4  christos 	}
    323      1.4  christos 
    324      1.4  christos 	db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
    325      1.4  christos 	if (lp == NULL)
    326      1.4  christos 		lp = p.p_lwps.lh_first;
    327      1.4  christos 
    328      1.4  christos 	db_printf("%s: pid %d proc %lx vmspace/map %lx flags %x\n",
    329      1.4  christos 	    p.p_comm, p.p_pid, (long)pp, (long)p.p_vmspace, p.p_flag);
    330      1.4  christos 
    331      1.4  christos 	while (lp != NULL) {
    332      1.4  christos 		db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
    333      1.4  christos 
    334      1.4  christos 		run = (l.l_stat == LSONPROC ||
    335  1.8.6.2        ad 		    (l.l_pflag & LP_RUNNING) != 0);
    336      1.4  christos 
    337      1.4  christos 		db_printf("%slwp %d", (run ? "> " : "  "), l.l_lid);
    338      1.4  christos 		if (l.l_name != NULL) {
    339      1.7      maxv 			db_read_string(l.l_name, MAXCOMLEN, db_nbuf);
    340      1.7      maxv 			db_nbuf[MAXCOMLEN] = '\0';
    341      1.4  christos 			db_printf(" [%s]", db_nbuf);
    342      1.4  christos 		}
    343      1.4  christos 		db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr);
    344      1.4  christos 
    345      1.4  christos 		if (l.l_cpu != NULL) {
    346      1.4  christos 			db_read_bytes((db_addr_t)
    347      1.4  christos 			    &l.l_cpu->ci_data.cpu_index,
    348      1.4  christos 			    sizeof(cpuno), (char *)&cpuno);
    349      1.4  christos 		} else
    350      1.4  christos 			cpuno = -1;
    351      1.4  christos 		db_printf("    stat %d flags %x cpu %d pri %d \n",
    352      1.4  christos 		    l.l_stat, l.l_flag, cpuno, l.l_priority);
    353      1.4  christos 
    354      1.4  christos 		if (l.l_wchan && l.l_wmesg) {
    355      1.7      maxv 			db_read_string(l.l_wmesg, MAXCOMLEN, wbuf);
    356      1.7      maxv 			wbuf[MAXCOMLEN] = '\0';
    357      1.4  christos 			db_printf("    wmesg %s wchan %lx\n",
    358      1.4  christos 			    wbuf, (long)l.l_wchan);
    359      1.4  christos 		}
    360      1.4  christos 
    361      1.4  christos 		lp = LIST_NEXT(&l, l_sibling);
    362      1.4  christos 	}
    363      1.4  christos }
    364