The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_proc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: bcb3b6abe0207151311f95f943c63dac


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.