On Fri, Jul 08, 2011 at 02:23:22PM +0200, Otto Moerbeek wrote:
> On Tue, Jul 05, 2011 at 07:09:38PM +0200, Otto Moerbeek wrote:
> 
> > On Tue, Jul 05, 2011 at 06:17:53PM +0200, Otto Moerbeek wrote:
> > 
> > > On Tue, Jul 05, 2011 at 12:08:26PM -0400, Ted Unangst wrote:
> > > 
> > > > On Tue, Jul 05, 2011, Otto Moerbeek wrote:
> > > > > Hi,
> > > > > 
> > > > > this adds decoding of some interesting structs to kdump. Mostly from
> > > > > FreeBSD, but adapted to our tree.
> > > > 
> > > > very cool, just a one comment below.
> > > > 
> > > > > error = copyout(mtod(m, caddr_t), SCARG(uap, asa), len);
> > > > > -     if (error == 0)
> > > > > +     if (error == 0) {
> > > > > +#ifdef KTRACE
> > > > > +             if (KTRPOINT(p, KTR_STRUCT))
> > > > > +                     ktrsockaddr(p, mtod(m, caddr_t), len);
> > > > > +#endif
> > > > > error = copyout(&len, SCARG(uap, alen), sizeof (len));
> > > > 
> > > > > error = copyout(&sb, SCARG(uap, ub), sizeof(sb));
> > > > > +#ifdef KTRACE
> > > > > +     if (error == 0 && KTRPOINT(p, KTR_STRUCT))
> > > > > +             ktrstat(p, &sb);
> > > > > +#endif
> > > > 
> > > > the new ktrace points are being added before, after, and between
> > > > existing copyout calls.  Can we make that consistent?  Probably best to
> > > > do it only if copyout succeeds.
> > > 
> > > My original idea was to add the trace point after the copyout that
> > > copies the struct.  But indeed, it might be better to do it only if
> > > both (if there are two) succeed.
> > > 
> > >   -Otto
> > 
> > Played a bit with that, but it becomes messy, because it is not always
> > obvious the mbuf is initalized. Putting the ktrace call immediately
> > after the corresponding copyout at least guarantees that the mbuf is
> > filled. 
> > 
> > For things like connect you want the struct even if the conect fails.
> > See e.g. the example I posted.
> > 
> >     -Otto
> 
> Regenered diff because there was a commit causing a conflict. 
> 
> I did not receive *any* testreport or review (apart from tedu's
> comment) so far. 
> 
> I'd hate it if bugs are detected only after this code goes into
> production. Now's the time to prevent that! 
> 
>       -Otto
> 
> 
> Index: lib/libc/sys/ktrace.2
> ===================================================================
> RCS file: /cvs/src/lib/libc/sys/ktrace.2,v
> retrieving revision 1.19
> diff -u -p -r1.19 ktrace.2
> --- lib/libc/sys/ktrace.2     17 Jul 2007 16:30:10 -0000      1.19
> +++ lib/libc/sys/ktrace.2     8 Jul 2011 12:14:30 -0000
> @@ -93,6 +93,7 @@ generate much output).
>  .It Dv KTRFAC_PSIG   Trace posted signals.
>  .It Dv KTRFAC_EMUL   Trace emulation changes.
>  .It Dv KTRFAC_CSW    Trace context switch points.
> +.It Dv KTRFAC_STRUCT Trace various structs
>  .It Dv KTRFAC_INHERIT        Inherit tracing to future children.
>  .El
>  .Pp
> Index: sys/kern/kern_descrip.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.86
> diff -u -p -r1.86 kern_descrip.c
> --- sys/kern/kern_descrip.c   2 Apr 2011 17:04:35 -0000       1.86
> +++ sys/kern/kern_descrip.c   8 Jul 2011 12:14:32 -0000
> @@ -59,6 +59,7 @@
>  #include <sys/syscallargs.h>
>  #include <sys/event.h>
>  #include <sys/pool.h>
> +#include <sys/ktrace.h>
>  
>  #include <uvm/uvm_extern.h>
>  
> @@ -632,6 +633,10 @@ sys_fstat(struct proc *p, void *v, regis
>               error = copyout((caddr_t)&ub, (caddr_t)SCARG(uap, sb),
>                   sizeof (ub));
>       }
> +#ifdef KTRACE
> +     if (error == 0 && KTRPOINT(p, KTR_STRUCT))
> +             ktrstat(p, &ub);
> +#endif
>       return (error);
>  }
>  
> Index: sys/kern/kern_ktrace.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_ktrace.c,v
> retrieving revision 1.52
> diff -u -p -r1.52 kern_ktrace.c
> --- sys/kern/kern_ktrace.c    7 Jul 2011 18:11:24 -0000       1.52
> +++ sys/kern/kern_ktrace.c    8 Jul 2011 12:14:32 -0000
> @@ -278,6 +278,30 @@ ktrcsw(struct proc *p, int out, int user
>       p->p_traceflag &= ~KTRFAC_ACTIVE;
>  }
>  
> +void
> +ktrstruct(struct proc *p, const char *name, const void *data, size_t datalen)
> +{
> +     struct ktr_header kth;
> +     void *buf;
> +     size_t buflen;
> +
> +     p->p_traceflag |= KTRFAC_ACTIVE;
> +     ktrinitheader(&kth, p, KTR_STRUCT);
> +     
> +     if (data == NULL)
> +             datalen = 0;
> +     buflen = strlen(name) + 1 + datalen;
> +     buf = malloc(buflen, M_TEMP, M_WAITOK);
> +     strlcpy(buf, name, buflen);
> +     bcopy(data, buf + strlen(name) + 1, datalen);
> +     kth.ktr_buf = buf;
> +     kth.ktr_len = buflen;
> +
> +     ktrwrite(p, &kth);
> +     free(buf, M_TEMP);
> +     p->p_traceflag &= ~KTRFAC_ACTIVE;
> +}
> +
>  /* Interface and common routines */
>  
>  /*
> Index: sys/kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.80
> diff -u -p -r1.80 uipc_syscalls.c
> --- sys/kern/uipc_syscalls.c  8 Jul 2011 05:01:27 -0000       1.80
> +++ sys/kern/uipc_syscalls.c  8 Jul 2011 12:14:33 -0000
> @@ -114,6 +114,10 @@ sys_bind(struct proc *p, void *v, regist
>       error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
>                        MT_SONAME);
>       if (error == 0) {
> +#ifdef KTRACE
> +     if (KTRPOINT(p, KTR_STRUCT))
> +             ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
> +#endif
>               error = sobind(fp->f_data, nam, p);
>               m_freem(nam);
>       }
> @@ -231,9 +235,14 @@ sys_accept(struct proc *p, void *v, regi
>                       namelen = nam->m_len;
>               /* SHOULD COPY OUT A CHAIN HERE */
>               if ((error = copyout(mtod(nam, caddr_t),
> -                 SCARG(uap, name), namelen)) == 0)
> +                 SCARG(uap, name), namelen)) == 0) {
> +#ifdef KTRACE
> +                     if (KTRPOINT(p, KTR_STRUCT))
> +                             ktrsockaddr(p, mtod(nam, caddr_t), namelen);
> +#endif
>                       error = copyout(&namelen, SCARG(uap, anamelen),
>                           sizeof (*SCARG(uap, anamelen)));
> +             }
>       }
>       /* if an error occurred, free the file descriptor */
>       if (error) {
> @@ -276,6 +285,10 @@ sys_connect(struct proc *p, void *v, reg
>                        MT_SONAME);
>       if (error)
>               goto bad;
> +#ifdef KTRACE
> +     if (KTRPOINT(p, KTR_STRUCT))
> +             ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
> +#endif
>       error = soconnect(so, nam);
>       if (error)
>               goto bad;
> @@ -481,6 +494,10 @@ sendit(struct proc *p, int s, struct msg
>                                MT_SONAME);
>               if (error)
>                       goto bad;
> +#ifdef KTRACE
> +             if (KTRPOINT(p, KTR_STRUCT))
> +                     ktrsockaddr(p, mtod(to, caddr_t), mp->msg_namelen);
> +#endif
>       }
>       if (mp->msg_control) {
>               if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))
> @@ -703,6 +720,11 @@ recvit(struct proc *p, int s, struct msg
>                       error = copyout(mtod(from, caddr_t), mp->msg_name, 
> alen);
>                       if (error)
>                               goto out;
> +#ifdef KTRACE
> +                     if (KTRPOINT(p, KTR_STRUCT))
> +                             ktrsockaddr(p, mtod(from, caddr_t), alen);
> +#endif
> +
>               }
>               mp->msg_namelen = alen;
>               if (namelenp &&
> @@ -917,8 +939,13 @@ sys_getsockname(struct proc *p, void *v,
>       if (len > m->m_len)
>               len = m->m_len;
>       error = copyout(mtod(m, caddr_t), SCARG(uap, asa), len);
> -     if (error == 0)
> +     if (error == 0) {
> +#ifdef KTRACE
> +             if (KTRPOINT(p, KTR_STRUCT))
> +                     ktrsockaddr(p, mtod(m, caddr_t), len);
> +#endif
>               error = copyout(&len, SCARG(uap, alen), sizeof (len));
> +     }
>  bad:
>       FRELE(fp);
>       if (m)
> @@ -961,8 +988,13 @@ sys_getpeername(struct proc *p, void *v,
>       if (len > m->m_len)
>               len = m->m_len;
>       error = copyout(mtod(m, caddr_t), SCARG(uap, asa), len);
> -     if (error == 0)
> +     if (error == 0) {
> +#ifdef KTRACE
> +             if (KTRPOINT(p, KTR_STRUCT))
> +                     ktrsockaddr(p, mtod(m, caddr_t), len);
> +#endif
>               error = copyout(&len, SCARG(uap, alen), sizeof (len));
> +     }
>  bad:
>       FRELE(fp);
>       m_freem(m);
> Index: sys/kern/vfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
> retrieving revision 1.170
> diff -u -p -r1.170 vfs_syscalls.c
> --- sys/kern/vfs_syscalls.c   8 Jul 2011 04:23:24 -0000       1.170
> +++ sys/kern/vfs_syscalls.c   8 Jul 2011 12:14:33 -0000
> @@ -53,6 +53,7 @@
>  #include <sys/dirent.h>
>  #include <sys/dkio.h>
>  #include <sys/disklabel.h>
> +#include <sys/ktrace.h>
>  
>  #include <sys/syscallargs.h>
>  
> @@ -1710,6 +1711,10 @@ dofstatat(struct proc *p, int fd, const 
>       if (suser(p, 0))
>               sb.st_gen = 0;
>       error = copyout(&sb, buf, sizeof(sb));
> +#ifdef KTRACE
> +     if (error == 0 && KTRPOINT(p, KTR_STRUCT))
> +             ktrstat(p, &sb);
> +#endif
>       return (error);
>  }
>  
> Index: sys/sys/ktrace.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/ktrace.h,v
> retrieving revision 1.10
> diff -u -p -r1.10 ktrace.h
> --- sys/sys/ktrace.h  2 Jun 2011 16:19:12 -0000       1.10
> +++ sys/sys/ktrace.h  8 Jul 2011 12:14:33 -0000
> @@ -134,6 +134,16 @@ struct ktr_csw {
>  #define KTR_EMUL     7
>       /* record contains emulation name */
>  
> +/*
> + * KTR_STRUCT - misc. structs
> + */
> +#define KTR_STRUCT   8
> +     /*
> +      * record contains null-terminated struct name followed by
> +      * struct contents
> +      */
> +struct sockaddr;
> +struct stat;
>  
>  /*
>   * kernel trace points (in p_traceflag)
> @@ -146,6 +156,8 @@ struct ktr_csw {
>  #define      KTRFAC_PSIG     (1<<KTR_PSIG)
>  #define KTRFAC_CSW   (1<<KTR_CSW)
>  #define KTRFAC_EMUL  (1<<KTR_EMUL)
> +#define KTRFAC_STRUCT   (1<<KTR_STRUCT)
> +
>  /*
>   * trace flags (also in p_traceflags)
>   */
> @@ -172,5 +184,12 @@ void ktrsyscall(struct proc *, register_
>  void ktrsysret(struct proc *, register_t, int, register_t);
>  
>  void ktrsettracevnode(struct proc *, struct vnode *);
> +
> +void    ktrstruct(struct proc *, const char *, const void *, size_t);
> +#define ktrsockaddr(p, s, l) \
> +     ktrstruct((p), "sockaddr", (s), (l))
> +#define ktrstat(p, s) \
> +     ktrstruct((p), "stat", (s), sizeof(struct stat))
> +
>  
>  #endif       /* !_KERNEL */
> Index: usr.bin/kdump/kdump.1
> ===================================================================
> RCS file: /cvs/src/usr.bin/kdump/kdump.1,v
> retrieving revision 1.17
> diff -u -p -r1.17 kdump.1
> --- usr.bin/kdump/kdump.1     31 May 2007 19:20:11 -0000      1.17
> +++ usr.bin/kdump/kdump.1     8 Jul 2011 12:14:33 -0000
> @@ -96,6 +96,9 @@ Show output only for the
>  specified.
>  .It Fl R
>  Display relative timestamps (time since previous entry).
> +.It Fl r
> +When decoding STRU records, display structure members such as UIDs,
> +GIDs, dates etc. symbolically instead of numerically.
>  .It Fl T
>  Display absolute timestamps for each entry (seconds since the Epoch).
>  .It Fl t Op ceinsw
> Index: usr.bin/kdump/kdump.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/kdump/kdump.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 kdump.c
> --- usr.bin/kdump/kdump.c     7 Jul 2011 06:39:48 -0000       1.54
> +++ usr.bin/kdump/kdump.c     8 Jul 2011 12:14:34 -0000
> @@ -37,6 +37,11 @@
>  #include <sys/ptrace.h>
>  #include <sys/socket.h>
>  #include <sys/sysctl.h>
> +#include <sys/socket.h>
> +#include <sys/un.h>
> +#include <sys/stat.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
>  #define _KERNEL
>  #include <sys/errno.h>
>  #undef _KERNEL
> @@ -46,7 +51,10 @@
>  #include <signal.h>
>  #include <stdio.h>
>  #include <stdlib.h>
> +#include <stdint.h>
>  #include <string.h>
> +#include <grp.h>
> +#include <pwd.h>
>  #include <unistd.h>
>  #include <vis.h>
>  
> @@ -55,11 +63,12 @@
>  #include "kdump_subr.h"
>  #include "extern.h"
>  
> -int timestamp, decimal, iohex, fancy = 1, tail, maxdata;
> +int timestamp, decimal, iohex, fancy = 1, tail, maxdata, resolv;
>  char *tracefile = DEF_TRACEFILE;
>  struct ktr_header ktr_header;
>  pid_t pid = -1;
>  
> +#define TIME_FORMAT  "%b %e %T %Y"
>  #define eqs(s1, s2)  (strcmp((s1), (s2)) == 0)
>  
>  #include <sys/syscall.h>
> @@ -120,6 +129,7 @@ static void ktrnamei(const char *, size_
>  static void ktrpsig(struct ktr_psig *);
>  static void ktrsyscall(struct ktr_syscall *);
>  static void ktrsysret(struct ktr_sysret *);
> +static void ktrstruct(char *, size_t);
>  static void setemul(const char *);
>  static void usage(void);
>  
> @@ -133,7 +143,7 @@ main(int argc, char *argv[])
>  
>       current = &emulations[0];       /* native */
>  
> -     while ((ch = getopt(argc, argv, "e:f:dlm:nRp:Tt:xX")) != -1)
> +     while ((ch = getopt(argc, argv, "e:f:dlm:nrRp:Tt:xX")) != -1)
>               switch (ch) {
>               case 'e':
>                       setemul(optarg);
> @@ -156,6 +166,9 @@ main(int argc, char *argv[])
>               case 'p':
>                       pid = atoi(optarg);
>                       break;
> +             case 'r':
> +                     resolv = 1;
> +                     break;
>               case 'R':
>                       timestamp = 2;  /* relative timestamp */
>                       break;
> @@ -228,6 +241,9 @@ main(int argc, char *argv[])
>               case KTR_EMUL:
>                       ktremul(m, ktrlen);
>                       break;
> +             case KTR_STRUCT:
> +                     ktrstruct(m, ktrlen);
> +                     break;
>               }
>               if (tail)
>                       (void)fflush(stdout);
> @@ -276,6 +292,9 @@ dumpheader(struct ktr_header *kth)
>       case KTR_EMUL:
>               type = "EMUL";
>               break;
> +     case KTR_STRUCT:
> +             type = "STRU";
> +             break;
>       default:
>               (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
>                   kth->ktr_type);
> @@ -870,13 +889,218 @@ ktrcsw(struct ktr_csw *cs)
>           cs->user ? "user" : "kernel");
>  }
>  
> +
> +
> +void
> +ktrsockaddr(struct sockaddr *sa)
> +{
> +/*
> + TODO: Support additional address families
> +     #include <netnatm/natm.h>
> +     struct sockaddr_natm    *natm;
> +     #include <netsmb/netbios.h>
> +     struct sockaddr_nb      *nb;
> +*/
> +     char addr[64];
> +
> +     /*
> +      * note: ktrstruct() has already verified that sa points to a
> +      * buffer at least sizeof(struct sockaddr) bytes long and exactly
> +      * sa->sa_len bytes long.
> +      */
> +     printf("struct sockaddr { ");
> +     sockfamilyname(sa->sa_family);
> +     printf(", ");
> +
> +#define check_sockaddr_len(n)                                        \
> +     if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
> +             printf("invalid");                              \
> +             break;                                          \
> +     }
> +
> +     switch(sa->sa_family) {
> +     case AF_INET: {
> +             struct sockaddr_in      *sa_in;
> +
> +             sa_in = (struct sockaddr_in *)sa;
> +             check_sockaddr_len(in);
> +             inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
> +             printf("%s:%u", addr, ntohs(sa_in->sin_port));
> +             break;
> +     }
> +#ifdef NETATALK
> +     case AF_APPLETALK: {
> +             struct sockaddr_at      *sa_at;
> +             struct netrange         *nr;
> +
> +             sa_at = (struct sockaddr_at *)sa;
> +             check_sockaddr_len(at);
> +             nr = &sa_at->sat_range.r_netrange;
> +             printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net),
> +                     sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet),
> +                     ntohs(nr->nr_lastnet), nr->nr_phase);
> +             break;
> +     }
> +#endif
> +     case AF_INET6: {
> +             struct sockaddr_in6     *sa_in6;
> +
> +             sa_in6 = (struct sockaddr_in6 *)sa;
> +             check_sockaddr_len(in6);
> +             inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
> +             printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
> +             break;
> +     }
> +#ifdef IPX
> +     case AF_IPX: {
> +             struct sockaddr_ipx     *sa_ipx;
> +
> +             sa_ipx = (struct sockaddr_ipx *)sa;
> +             check_sockaddr_len(ipx);
> +             /* XXX wish we had ipx_ntop */
> +             printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
> +             break;
> +     }
> +#endif
> +     case AF_UNIX: {
> +             struct sockaddr_un *sa_un;
> +
> +             sa_un = (struct sockaddr_un *)sa;
> +             if (sa_un->sun_len <= sizeof(sa_un->sun_len) +
> +                 sizeof(sa_un->sun_family)) {
> +                     printf("invalid");
> +                     break;
> +             }
> +             printf("\"%.*s\"", (int)(sa_un->sun_len -
> +                 sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),
> +                 sa_un->sun_path);
> +             break;
> +     }
> +     default:
> +             printf("unknown address family");
> +     }
> +     printf(" }\n");
> +}
> +
> +void
> +ktrstat(struct stat *statp)
> +{
> +     char mode[12], timestr[PATH_MAX + 4];
> +     struct passwd *pwd;
> +     struct group  *grp;
> +     struct tm *tm;
> +
> +     /*
> +      * note: ktrstruct() has already verified that statp points to a
> +      * buffer exactly sizeof(struct stat) bytes long.
> +      */
> +     printf("struct stat {");
> +     strmode(statp->st_mode, mode);
> +     printf("dev=%d, ino=%u, mode=%s, nlink=%u, ",
> +         statp->st_dev, statp->st_ino, mode, statp->st_nlink);
> +     if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
> +             printf("uid=%u, ", statp->st_uid);
> +     else
> +             printf("uid=\"%s\", ", pwd->pw_name);
> +     if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
> +             printf("gid=%u, ", statp->st_gid);
> +     else
> +             printf("gid=\"%s\", ", grp->gr_name);
> +     printf("rdev=%d, ", statp->st_rdev);
> +     printf("atime=");
> +     if (resolv == 0)
> +             printf("%jd", (intmax_t)statp->st_atim.tv_sec);
> +     else {
> +             tm = localtime(&statp->st_atim.tv_sec);
> +             (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
> +             printf("\"%s\"", timestr);
> +     }
> +     if (statp->st_atim.tv_nsec != 0)
> +             printf(".%09ld, ", statp->st_atim.tv_nsec);
> +     else
> +             printf(", ");
> +     printf("stime=");
> +     if (resolv == 0)
> +             printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
> +     else {
> +             tm = localtime(&statp->st_mtim.tv_sec);
> +             (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
> +             printf("\"%s\"", timestr);
> +     }
> +     if (statp->st_mtim.tv_nsec != 0)
> +             printf(".%09ld, ", statp->st_mtim.tv_nsec);
> +     else
> +             printf(", ");
> +     printf("ctime=");
> +     if (resolv == 0)
> +             printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
> +     else {
> +             tm = localtime(&statp->st_ctim.tv_sec);
> +             (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
> +             printf("\"%s\"", timestr);
> +     }
> +     if (statp->st_ctim.tv_nsec != 0)
> +             printf(".%09ld, ", statp->st_ctim.tv_nsec);
> +     else
> +             printf(", ");
> +     printf("size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",
> +         statp->st_size, statp->st_blocks, statp->st_blksize,
> +         statp->st_flags, statp->st_gen);
> +     printf(" }\n");
> +}
> +
> +void
> +ktrstruct(char *buf, size_t buflen)
> +{
> +     char *name, *data;
> +     size_t namelen, datalen;
> +     int i;
> +     struct stat sb;
> +     struct sockaddr_storage ss;
> +
> +     for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';
> +          ++namelen)
> +             /* nothing */;
> +     if (namelen == buflen)
> +             goto invalid;
> +     if (name[namelen] != '\0')
> +             goto invalid;
> +     data = buf + namelen + 1;
> +     datalen = buflen - namelen - 1;
> +     if (datalen == 0)
> +             goto invalid;
> +     /* sanity check */
> +     for (i = 0; i < namelen; ++i)
> +             if (!isalpha((unsigned char)name[i]))
> +                     goto invalid;
> +     if (strcmp(name, "stat") == 0) {
> +             if (datalen != sizeof(struct stat))
> +                     goto invalid;
> +             memcpy(&sb, data, datalen);
> +             ktrstat(&sb);
> +     } else if (strcmp(name, "sockaddr") == 0) {
> +             if (datalen > sizeof(ss))
> +                     goto invalid;
> +             memcpy(&ss, data, datalen);
> +             if ((ss.ss_family != AF_UNIX && 
> +                 datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)
> +                     goto invalid;
> +             ktrsockaddr((struct sockaddr *)&ss);
> +     } else {
> +             printf("unknown structure\n");
> +     }
> +     return;
> +invalid:
> +     printf("invalid record\n");
> +}
> +
>  static void
>  usage(void)
>  {
>  
>       extern char *__progname;
>       fprintf(stderr, "usage: %s "
> -         "[-dlnRTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
> +         "[-dlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
>           "%*s[-t [ceinsw]]\n",
>           __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
>       exit(1);
> Index: usr.bin/kdump/kdump_subr.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/kdump/kdump_subr.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 kdump_subr.h
> --- usr.bin/kdump/kdump_subr.h        4 Jul 2011 06:44:52 -0000       1.2
> +++ usr.bin/kdump/kdump_subr.h        8 Jul 2011 12:14:34 -0000
> @@ -40,6 +40,7 @@ void sockoptlevelname(int);
>  void sockdomainname(int);
>  void sockipprotoname(int);
>  void socktypename(int);
> +void sockfamilyname(int);
>  void thrcreateflagsname(int);
>  void mlockallname(int);
>  void shmatname(int);
> Index: usr.bin/kdump/mksubr
> ===================================================================
> RCS file: /cvs/src/usr.bin/kdump/mksubr,v
> retrieving revision 1.4
> diff -u -p -r1.4 mksubr
> --- usr.bin/kdump/mksubr      4 Jul 2011 06:44:52 -0000       1.4
> +++ usr.bin/kdump/mksubr      8 Jul 2011 12:14:34 -0000
> @@ -365,7 +365,7 @@ auto_switch_type "sigprocmaskhowname" "S
>  auto_switch_type "minheritname" "INHERIT_[A-Z]+[[:space:]]+[0-9]+" 
> "sys/mman.h"
>  #auto_switch_type "quotactlname" "Q_[A-Z]+[[:space:]]+0x[0-9]+" 
> "ufs/ufs/quota.h"
>  auto_if_type "sockdomainname" "PF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
> -#auto_if_type "sockfamilyname" "AF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
> +auto_if_type "sockfamilyname" "AF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
>  auto_if_type "sockipprotoname" "IPPROTO_[[:alnum:]]+[[:space:]]+" 
> "netinet/in.h"
>  auto_switch_type "sockoptname" "SO_[A-Z]+[[:space:]]+0x[0-9]+" "sys/socket.h"
>  auto_switch_type "socktypename" "SOCK_[A-Z]+[[:space:]]+[1-9]+[0-9]*" 
> "sys/socket.h"
> Index: usr.bin/ktrace/ktrace.1
> ===================================================================
> RCS file: /cvs/src/usr.bin/ktrace/ktrace.1,v
> retrieving revision 1.20
> diff -u -p -r1.20 ktrace.1
> --- usr.bin/ktrace/ktrace.1   25 Jun 2011 18:44:43 -0000      1.20
> +++ usr.bin/ktrace/ktrace.1   8 Jul 2011 12:14:34 -0000
> @@ -108,8 +108,9 @@ The default flags are
>  .Cm e ,
>  .Cm i ,
>  .Cm n ,
> -and
> -.Cm s .
> +.Cm s ,
> +and 
> +.Cm t .
>  The following table equates the letters with the tracepoints:
>  .Pp
>  .Bl -tag -width flag -offset indent -compact
> @@ -123,6 +124,8 @@ trace I/O
>  trace namei translations
>  .It Cm s
>  trace signal processing
> +.It Cm t
> +trace various structures
>  .It Cm w
>  trace context switch points
>  .It Cm +
> Index: usr.bin/ktrace/ktrace.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/ktrace/ktrace.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 ktrace.h
> --- usr.bin/ktrace/ktrace.h   3 Jun 2003 02:56:09 -0000       1.3
> +++ usr.bin/ktrace/ktrace.h   8 Jul 2011 12:14:34 -0000
> @@ -31,7 +31,7 @@
>   */
>  
>  #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
> -               KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL)
> +               KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_STRUCT)
>  
>  #define ALL_POINTS (DEF_POINTS | KTRFAC_CSW)
>  
> Index: usr.bin/ktrace/subr.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ktrace/subr.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 subr.c
> --- usr.bin/ktrace/subr.c     27 Oct 2009 23:59:39 -0000      1.6
> +++ usr.bin/ktrace/subr.c     8 Jul 2011 12:14:34 -0000
> @@ -68,6 +68,9 @@ getpoints(s)
>               case 'w':
>                       facs |= KTRFAC_CSW;
>                       break;
> +             case 't':
> +                     facs |= KTRFAC_STRUCT;
> +                     break;
>               case '+':
>                       facs |= DEF_POINTS;
>                       break;
> 

Maybe I'm missing something but I get the following with your diff and
an uptodate source tree.

/usr/src/usr.bin/ktrace/ktrace.c: In function 'main':
/usr/src/usr.bin/ktrace/ktrace.c:66: error: 'KTRFAC_STRUCT' undeclared
(first use in this function)
/usr/src/usr.bin/ktrace/ktrace.c:66: error: (Each undeclared identifier
is reported only once
/usr/src/usr.bin/ktrace/ktrace.c:66: error: for each function it appears
in.)
*** Error code 1

kdump(1) compiles fine.

Reply via email to