Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src introduce a new way of handling SYSCALL_DEBUG messages -- se...



details:   https://anonhg.NetBSD.org/src/rev/748653b0b30d
branches:  trunk
changeset: 811406:748653b0b30d
user:      mrg <mrg%NetBSD.org@localhost>
date:      Thu Oct 29 00:27:08 2015 +0000

description:
introduce a new way of handling SYSCALL_DEBUG messages -- send them to
a kernel history, settable via the SCDEBUG_KERNHIST flag.

this requires a fairly significantly different set of messages than the
normal debug as histories are restricted:
        - each message can take one literal format string and upto 4
          arguments
        - the arguments can not be strings if you want vmstat -u to
          work (this could be fixed, and i might, as it would be nice
          if we could print syscall names as well as numbers.)

introduce SCDEBUG_DEFAULT that is settable in the kernel config.

fix a problem in kernhist_dump_histories() where it would crash when a
history with no allocated entries was found.

extend kernhist_dumpmask() to handle the usbhist and scdebughist.

diffstat:

 share/man/man4/options.4 |   41 +++++++++-
 sys/kern/init_main.c     |    6 +-
 sys/kern/kern_history.c  |   30 +++++++-
 sys/kern/kern_xxx.c      |  179 +++++++++++++++++++++++++++++++++++++++-------
 sys/sys/kernhist.h       |    4 +-
 sys/sys/systm.h          |    3 +-
 6 files changed, 224 insertions(+), 39 deletions(-)

diffs (truncated from 460 to 300 lines):

diff -r ff5990fc9eee -r 748653b0b30d share/man/man4/options.4
--- a/share/man/man4/options.4  Thu Oct 29 00:18:55 2015 +0000
+++ b/share/man/man4/options.4  Thu Oct 29 00:27:08 2015 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: options.4,v 1.449 2015/08/20 11:05:06 wiz Exp $
+.\"    $NetBSD: options.4,v 1.450 2015/10/29 00:27:08 mrg Exp $
 .\"
 .\" Copyright (c) 1996
 .\"    Perry E. Metzger.  All rights reserved.
@@ -30,7 +30,7 @@
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\"
-.Dd August 20, 2015
+.Dd October 28, 2015
 .Dt OPTIONS 4
 .Os
 .Sh NAME
@@ -668,7 +668,9 @@
 from DDB.
 See the kernel source file
 .Pa sys/kern/kern_history.c
-for details.
+and the
+.Xr kernhist 9
+manual for details.
 .It Cd options KERNHIST_PRINT
 Prints the kernel history logs on the system console as entries are added.
 Note that the output is
@@ -1508,6 +1510,36 @@
 for details.
 .Em NOTE :
 not available on all architectures.
+.It Cd options SCDEBUG_DEFAULT
+Used with the
+.Cd options SYSCALL_DEBUG
+described below to choose which types of events are displayed.
+.Pp
+.Bl -tag -width "SCDEBUG_KERNHIST" -compact -offset indent
+.It Dv SCDEBUG_CALLS
+Show system call entry points.
+.It Dv SCDEBUG_RETURNS
+Show system call exit points.
+.It Dv SCDEBUG_ALL
+Show all system call requestes, including unimplemented calls.
+.It Dv SCDEBUG_SHOWARGS
+Show the arguments provided.
+.It Dv SCDEBUG_KERNHIST
+Store a restricted form of the system call debug in a kernel history
+instead of printing it to the console.  This option relies upon
+.Cd options KERNHIST .
+.El
+.Pp
+The default value is
+.Dv (SCDEBUG_CALLS|SCDEBUG_RETURNS|SCDEBUG_SHOWARGS) .
+.It Cd options SYSCALL_DEBUG
+Useful for debugging system call issues, usually in early single user bringup.
+By default, writes entries to the system console for most system call events.
+Can be configured with the
+.Cd options SCDEBUG_DEFAULT
+option to to use the
+.Cd options KERNHIST
+facility instead.
 .It Cd options SYSCALL_STATS
 Count the number of times each system call number is called.
 The values can be read through the sysctl interface and displayed using
@@ -2733,7 +2765,8 @@
 .Xr quotaon 8 ,
 .Xr rpc.rquotad 8 ,
 .Xr sysctl 8 ,
-.Xr in_getifa 9
+.Xr in_getifa 9 ,
+.Xr kernhist 9
 .Sh HISTORY
 The
 .Nm
diff -r ff5990fc9eee -r 748653b0b30d sys/kern/init_main.c
--- a/sys/kern/init_main.c      Thu Oct 29 00:18:55 2015 +0000
+++ b/sys/kern/init_main.c      Thu Oct 29 00:27:08 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: init_main.c,v 1.471 2015/10/17 13:52:52 jmcneill Exp $ */
+/*     $NetBSD: init_main.c,v 1.472 2015/10/29 00:27:08 mrg Exp $      */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.471 2015/10/17 13:52:52 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.472 2015/10/29 00:27:08 mrg Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipsec.h"
@@ -601,6 +601,8 @@
 
        procinit_sysctl();
 
+       scdebug_init();
+
        /*
         * Create process 1 (init(8)).  We do this now, as Unix has
         * historically had init be process 1, and changing this would
diff -r ff5990fc9eee -r 748653b0b30d sys/kern/kern_history.c
--- a/sys/kern/kern_history.c   Thu Oct 29 00:18:55 2015 +0000
+++ b/sys/kern/kern_history.c   Thu Oct 29 00:27:08 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_history.c,v 1.1 2011/05/17 04:18:06 mrg Exp $      */
+/*     $NetBSD: kern_history.c,v 1.2 2015/10/29 00:27:08 mrg Exp $      */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -33,18 +33,30 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_history.c,v 1.1 2011/05/17 04:18:06 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_history.c,v 1.2 2015/10/29 00:27:08 mrg Exp $");
 
 #include "opt_kernhist.h"
+#include "opt_ddb.h"
 #include "opt_uvmhist.h"
-#include "opt_ddb.h"
+#include "opt_usb.h"
+#include "opt_syscall_debug.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/cpu.h>
 #include <sys/kernhist.h>
 
+#ifdef UVMHIST
 #include <uvm/uvm.h>
+#endif
+
+#ifdef USB_DEBUG
+#include <dev/usb/usbhist.h>
+#endif
+
+#ifdef SYSCALL_DEBUG
+KERNHIST_DECL(scdebughist);
+#endif
 
 /*
  * globals
@@ -112,6 +124,8 @@
 restart:
                        if (cur[lcv] == -1)
                                continue;
+                       if (!hists[lcv]->e)
+                               continue;
 
                        /*
                         * if the format is empty, go to the next entry
@@ -174,6 +188,16 @@
                hists[i++] = &loanhist;
 #endif
 
+#ifdef USB_DEBUG
+       if ((bitmask & KERNHIST_USBHIST) || bitmask == 0)
+               hists[i++] = &usbhist;
+#endif
+
+#ifdef SYSCALL_DEBUG
+       if ((bitmask & KERNHIST_SCDEBUGHIST) || bitmask == 0)
+               hists[i++] = &scdebughist;
+#endif
+
        hists[i] = NULL;
 
        kernhist_dump_histories(hists);
diff -r ff5990fc9eee -r 748653b0b30d sys/kern/kern_xxx.c
--- a/sys/kern/kern_xxx.c       Thu Oct 29 00:18:55 2015 +0000
+++ b/sys/kern/kern_xxx.c       Thu Oct 29 00:27:08 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_xxx.c,v 1.72 2011/09/01 18:25:44 matt Exp $       */
+/*     $NetBSD: kern_xxx.c,v 1.73 2015/10/29 00:27:08 mrg Exp $        */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -32,10 +32,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_xxx.c,v 1.72 2011/09/01 18:25:44 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_xxx.c,v 1.73 2015/10/29 00:27:08 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_syscall_debug.h"
+#include "opt_kernhist.h"
 #endif
 
 #include <sys/param.h>
@@ -49,6 +50,7 @@
 #include <sys/syscall.h>
 #include <sys/syscallargs.h>
 #include <sys/kauth.h>
+#include <sys/kernhist.h>
 
 /* ARGSUSED */
 int
@@ -102,42 +104,134 @@
 #ifdef SYSCALL_DEBUG
 #define        SCDEBUG_CALLS           0x0001  /* show calls */
 #define        SCDEBUG_RETURNS         0x0002  /* show returns */
-#define        SCDEBUG_ALL             0x0004  /* even syscalls that are implemented */
+#define        SCDEBUG_ALL             0x0004  /* even syscalls that are not implemented */
 #define        SCDEBUG_SHOWARGS        0x0008  /* show arguments to calls */
+#define        SCDEBUG_KERNHIST        0x0010  /* use kernhist instead of printf */
+
+#ifndef SCDEBUG_DEFAULT
+#define SCDEBUG_DEFAULT (SCDEBUG_CALLS|SCDEBUG_RETURNS|SCDEBUG_SHOWARGS)
+#endif
+
+int    scdebug = SCDEBUG_DEFAULT;
 
-#if 0
-int    scdebug = SCDEBUG_CALLS|SCDEBUG_RETURNS|SCDEBUG_SHOWARGS;
+#ifdef KERNHIST
+KERNHIST_DEFINE(scdebughist);
+#define SCDEBUG_KERNHIST_FUNC(a)               KERNHIST_FUNC(a)
+#define SCDEBUG_KERNHIST_CALLED(a)             KERNHIST_CALLED(a)
+#define SCDEBUG_KERNHIST_LOG(a,b,c,d,e,f)      KERNHIST_LOG(a,b,c,d,e,f)
 #else
-int    scdebug = SCDEBUG_CALLS|SCDEBUG_RETURNS|SCDEBUG_SHOWARGS|SCDEBUG_ALL;
+#define SCDEBUG_KERNHIST_FUNC(a)               /* nothing */
+#define SCDEBUG_KERNHIST_CALLED(a)             /* nothing */
+#define SCDEBUG_KERNHIST_LOG(a,b,c,d,e,f)      /* nothing */
+/* The non-kernhist support version can elide all this code easily. */
+#undef SCDEBUG_KERNHIST
+#define        SCDEBUG_KERNHIST 0
+#endif
+
+#ifdef __HAVE_MINIMAL_EMUL
+#define CODE_NOT_OK(code, em)  ((int)(code) < 0)
+#else
+#define CODE_NOT_OK(code, em)  (((int)(code) < 0) || \
+                                ((int)(code) >= (em)->e_nsysent))
 #endif
 
 void
 scdebug_call(register_t code, const register_t args[])
 {
+       SCDEBUG_KERNHIST_FUNC("scdebug_call");
        struct lwp *l = curlwp;
        struct proc *p = l->l_proc;
        const struct sysent *sy;
        const struct emul *em;
        int i;
 
-       if (!(scdebug & SCDEBUG_CALLS))
+       if ((scdebug & SCDEBUG_CALLS) == 0)
                return;
 
+       if (scdebug & SCDEBUG_KERNHIST)
+               SCDEBUG_KERNHIST_CALLED(scdebughist);
+
        em = p->p_emul;
        sy = &em->e_sysent[code];
-       if (!(scdebug & SCDEBUG_ALL || (int)code < 0
-#ifndef __HAVE_MINIMAL_EMUL
-           || code >= em->e_nsysent
-#endif
-           || sy->sy_call == sys_nosys))
+
+       if ((scdebug & SCDEBUG_ALL) == 0 &&
+           (CODE_NOT_OK(code, em) || sy->sy_call == sys_nosys)) {
+               if (scdebug & SCDEBUG_KERNHIST)
+                       SCDEBUG_KERNHIST_LOG(scdebughist, "", 0, 0, 0, 0);
                return;
+       }
+
+       /*
+        * The kernhist version of scdebug needs to restrict the usage
+        * compared to the normal version.  histories must avoid these
+        * sorts of usage:
+        *
+        *      - the format string *must* be literal, as it is used
+        *        at display time in the kernel or userland
+        *      - strings in the format will cause vmstat -u to crash
+        *        so avoid using %s formats
+        *
+        * to avoid these, we have a fairly long block to print args
+        * as the format needs to change for each, and we can't just
+        * call printf() on each argument until we're done.
+        */
+       if (scdebug & SCDEBUG_KERNHIST) {
+               if (CODE_NOT_OK(code, em)) {
+                       SCDEBUG_KERNHIST_LOG(scdebughist, 
+                           "pid %d:%d: OUT OF RANGE (%ld)",
+                           p->p_pid, l->l_lid, code, 0);
+               } else {
+                       SCDEBUG_KERNHIST_LOG(scdebughist,
+                           "pid %d:%d: num %d call %p",
+                           p->p_pid, l->l_lid, code, sy->sy_call);
+                       if ((scdebug & SCDEBUG_SHOWARGS) == 0)
+                               return;
+
+                       if (sy->sy_narg > 7) {
+                               SCDEBUG_KERNHIST_LOG(scdebughist,



Home | Main Index | Thread Index | Old Index