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/kern/kern_scdebug.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: kern_scdebug.c,v 1.2 2019/03/14 19:51:49 palle Exp $   */
    2 
    3 /*
    4  * Copyright (c) 2015 Matthew R. Green
    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  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Copyright (c) 1982, 1986, 1989, 1993
   31  *      The Regents of the University of California.  All rights reserved.
   32  *
   33  * Redistribution and use in source and binary forms, with or without
   34  * modification, are permitted provided that the following conditions
   35  * are met:
   36  * 1. Redistributions of source code must retain the above copyright
   37  *    notice, this list of conditions and the following disclaimer.
   38  * 2. Redistributions in binary form must reproduce the above copyright
   39  *    notice, this list of conditions and the following disclaimer in the
   40  *    documentation and/or other materials provided with the distribution.
   41  * 3. Neither the name of the University nor the names of its contributors
   42  *    may be used to endorse or promote products derived from this software
   43  *    without specific prior written permission.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  *
   57  *      @(#)kern_xxx.c  8.3 (Berkeley) 2/14/95
   58  *      from: NetBSD: kern_xxx.c,v 1.74 2017/10/28 00:37:11 pgoyette Exp
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: kern_scdebug.c,v 1.2 2019/03/14 19:51:49 palle Exp $");
   63 
   64 #ifdef _KERNEL_OPT
   65 #include "opt_syscall_debug.h"
   66 #include "opt_kernhist.h"
   67 #endif
   68 
   69 #include <sys/param.h>
   70 #include <sys/systm.h>
   71 #include <sys/kernel.h>
   72 #include <sys/proc.h>
   73 #include <sys/sysctl.h>
   74 #include <sys/mount.h>
   75 #include <sys/syscall.h>
   76 #include <sys/syscallargs.h>
   77 #include <sys/kernhist.h>
   78 
   79 /*
   80  * Pull in the indirect syscall functions here.
   81  * They are only actually used if the ports syscall entry code
   82  * doesn't special-case SYS_SYSCALL and SYS___SYSCALL
   83  *
   84  * In some cases the generated code for the two functions is identical,
   85  * but there isn't a MI way of determining that - so we don't try.
   86  */
   87 
   88 #define SYS_SYSCALL sys_syscall
   89 #include "sys_syscall.c"
   90 #undef SYS_SYSCALL
   91 
   92 #define SYS_SYSCALL sys___syscall
   93 #include "sys_syscall.c"
   94 #undef SYS_SYSCALL
   95 
   96 #ifdef SYSCALL_DEBUG
   97 #define SCDEBUG_CALLS           0x0001  /* show calls */
   98 #define SCDEBUG_RETURNS         0x0002  /* show returns */
   99 #define SCDEBUG_ALL             0x0004  /* even syscalls that are not implemented */
  100 #define SCDEBUG_SHOWARGS        0x0008  /* show arguments to calls */
  101 #define SCDEBUG_KERNHIST        0x0010  /* use kernhist instead of printf */
  102 
  103 #ifndef SCDEBUG_DEFAULT
  104 #define SCDEBUG_DEFAULT (SCDEBUG_CALLS|SCDEBUG_RETURNS|SCDEBUG_SHOWARGS)
  105 #endif
  106 
  107 int     scdebug = SCDEBUG_DEFAULT;
  108 
  109 #ifdef KERNHIST
  110 KERNHIST_DEFINE(scdebughist);
  111 #define SCDEBUG_KERNHIST_FUNC(a)                KERNHIST_FUNC(a)
  112 #define SCDEBUG_KERNHIST_CALLED(a)              KERNHIST_CALLED(a)
  113 #define SCDEBUG_KERNHIST_LOG(a,b,c,d,e,f)       KERNHIST_LOG(a,b,c,d,e,f)
  114 #else
  115 #define SCDEBUG_KERNHIST_FUNC(a)                {} /* nothing */
  116 #define SCDEBUG_KERNHIST_CALLED(a)              {} /* nothing */
  117 #define SCDEBUG_KERNHIST_LOG(a,b,c,d,e,f)       {} /* nothing */
  118 /* The non-kernhist support version can elide all this code easily. */
  119 #undef  SCDEBUG_KERNHIST
  120 #define SCDEBUG_KERNHIST 0
  121 #endif
  122 
  123 #ifdef __HAVE_MINIMAL_EMUL
  124 #define CODE_NOT_OK(code, em)   ((int)(code) < 0)
  125 #else
  126 #define CODE_NOT_OK(code, em)   (((int)(code) < 0) || \
  127                                  ((int)(code) >= (em)->e_nsysent))
  128 #endif
  129 
  130 void
  131 scdebug_call(register_t code, const register_t args[])
  132 {
  133         SCDEBUG_KERNHIST_FUNC("scdebug_call");
  134         struct lwp *l = curlwp;
  135         struct proc *p = l->l_proc;
  136         const struct sysent *sy;
  137         const struct emul *em;
  138         int i;
  139 
  140         if ((scdebug & SCDEBUG_CALLS) == 0)
  141                 return;
  142 
  143         if (scdebug & SCDEBUG_KERNHIST)
  144                 SCDEBUG_KERNHIST_CALLED(scdebughist);
  145 
  146         em = p->p_emul;
  147         sy = &em->e_sysent[code];
  148 
  149         if ((scdebug & SCDEBUG_ALL) == 0 &&
  150             (CODE_NOT_OK(code, em) || sy->sy_call == sys_nosys)) {
  151                 if (scdebug & SCDEBUG_KERNHIST)
  152                         SCDEBUG_KERNHIST_LOG(scdebughist, "", 0, 0, 0, 0);
  153                 return;
  154         }
  155 
  156         /*
  157          * The kernhist version of scdebug needs to restrict the usage
  158          * compared to the normal version.  histories must avoid these
  159          * sorts of usage:
  160          *
  161          *      - the format string *must* be literal, as it is used
  162          *        at display time in the kernel or userland
  163          *      - strings in the format will cause vmstat -u to crash
  164          *        so avoid using %s formats
  165          *
  166          * to avoid these, we have a fairly long block to print args
  167          * as the format needs to change for each, and we can't just
  168          * call printf() on each argument until we're done.
  169          */
  170         if (scdebug & SCDEBUG_KERNHIST) {
  171                 if (CODE_NOT_OK(code, em)) {
  172                         SCDEBUG_KERNHIST_LOG(scdebughist, 
  173                             "pid %jd:%jd: OUT OF RANGE (%jd)",
  174                             p->p_pid, l->l_lid, code, 0);
  175                 } else {
  176                         SCDEBUG_KERNHIST_LOG(scdebughist,
  177                             "pid %jd:%jd: num %jd call %#jx",
  178                             p->p_pid, l->l_lid, code, (uintptr_t)sy->sy_call);
  179                         if ((scdebug & SCDEBUG_SHOWARGS) == 0)
  180                                 return;
  181 
  182                         if (sy->sy_narg > 7) {
  183                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  184                                     "args[4-7]: (%jx, %jx, %jx, %jx, ...)",
  185                                     (long)args[4], (long)args[5],
  186                                     (long)args[6], (long)args[7]);
  187                         } else if (sy->sy_narg > 6) {
  188                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  189                                     "args[4-6]: (%jx, %jx, %jx)",
  190                                     (long)args[4], (long)args[5],
  191                                     (long)args[6], 0);
  192                         } else if (sy->sy_narg > 5) {
  193                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  194                                     "args[4-5]: (%jx, %jx)",
  195                                     (long)args[4], (long)args[5], 0, 0);
  196                         } else if (sy->sy_narg == 5) {
  197                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  198                                     "args[4]: (%jx)",
  199                                     (long)args[4], 0, 0, 0);
  200                         }
  201 
  202                         if (sy->sy_narg > 3) {
  203                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  204                                     "args[0-3]: (%jx, %jx, %jx, %jx, ...)",
  205                                     (long)args[0], (long)args[1],
  206                                     (long)args[2], (long)args[3]);
  207                         } else if (sy->sy_narg > 2) {
  208                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  209                                     "args[0-2]: (%jx, %jx, %jx)",
  210                                     (long)args[0], (long)args[1],
  211                                     (long)args[2], 0);
  212                         } else if (sy->sy_narg > 1) {
  213                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  214                                     "args[0-1]: (%jx, %jx)",
  215                                     (long)args[0], (long)args[1], 0, 0);
  216                         } else if (sy->sy_narg == 1) {
  217                                 SCDEBUG_KERNHIST_LOG(scdebughist,
  218                                     "args[0]: (%jx)",
  219                                     (long)args[0], 0, 0, 0);
  220                         }
  221                 }
  222                 return;
  223         }
  224 
  225         printf("proc %d (%s): %s num ", p->p_pid, p->p_comm, em->e_name);
  226         if (CODE_NOT_OK(code, em))
  227                 printf("OUT OF RANGE (%ld)", (long)code);
  228         else {
  229                 printf("%ld call: %s", (long)code, em->e_syscallnames[code]);
  230                 if (scdebug & SCDEBUG_SHOWARGS) {
  231                         printf("(");
  232                         for (i = 0; i < sy->sy_argsize/sizeof(register_t); i++)
  233                                 printf("%s0x%lx", i == 0 ? "" : ", ",
  234                                     (long)args[i]);
  235                         printf(")");
  236                 }
  237         }
  238         printf("\n");
  239 }
  240 
  241 void
  242 scdebug_ret(register_t code, int error, const register_t retval[])
  243 {
  244         SCDEBUG_KERNHIST_FUNC("scdebug_ret");
  245         struct lwp *l = curlwp;
  246         struct proc *p = l->l_proc;
  247         const struct sysent *sy;
  248         const struct emul *em;
  249 
  250         if ((scdebug & SCDEBUG_RETURNS) == 0)
  251                 return;
  252 
  253         if (scdebug & SCDEBUG_KERNHIST)
  254                 SCDEBUG_KERNHIST_CALLED(scdebughist);
  255 
  256         em = p->p_emul;
  257         sy = &em->e_sysent[code];
  258         if ((scdebug & SCDEBUG_ALL) == 0 &&
  259             (CODE_NOT_OK(code, em) || sy->sy_call == sys_nosys)) {
  260                 if (scdebug & SCDEBUG_KERNHIST)
  261                         SCDEBUG_KERNHIST_LOG(scdebughist, "", 0, 0, 0, 0);
  262                 return;
  263         }
  264 
  265         if (scdebug & SCDEBUG_KERNHIST) {
  266                 if (CODE_NOT_OK(code, em)) {
  267                         SCDEBUG_KERNHIST_LOG(scdebughist, 
  268                             "pid %jd:%jd: OUT OF RANGE (%jd)",
  269                             p->p_pid, l->l_lid, code, 0);
  270                 } else {
  271                         SCDEBUG_KERNHIST_LOG(scdebughist,
  272                             "pid %jd:%jd: num %jd",
  273                             p->p_pid, l->l_lid, code, 0);
  274                         SCDEBUG_KERNHIST_LOG(scdebughist,
  275                             "ret: err = %jd, rv = 0x%jx,0x%jx",
  276                             error, (long)retval[0], (long)retval[1], 0);
  277                 }
  278                 return;
  279         }
  280 
  281         printf("proc %d (%s): %s num ", p->p_pid, p->p_comm, em->e_name);
  282         if (CODE_NOT_OK(code, em))
  283                 printf("OUT OF RANGE (%ld)", (long)code);
  284         else
  285                 printf("%ld ret %s: err = %d, rv = 0x%lx,0x%lx", (long)code,
  286                     em->e_syscallnames[code], error,
  287                     (long)retval[0], (long)retval[1]);
  288         printf("\n");
  289 }
  290 #endif /* SYSCALL_DEBUG */
  291 
  292 #ifndef SCDEBUG_KERNHIST_SIZE
  293 #define SCDEBUG_KERNHIST_SIZE 500
  294 #endif
  295 
  296 void
  297 scdebug_init(void)
  298 {
  299 #if defined(SYSCALL_DEBUG) && defined(KERNHIST)
  300         /* Setup scdebughist kernel history */
  301         KERNHIST_INIT(scdebughist, SCDEBUG_KERNHIST_SIZE);
  302 #endif
  303 }

Cache object: f03bb98fab0ca813fcd3e60e2b01e97b


[ 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.