On Mon, Jul 18, 2011 at 11:35:42AM +0200, Otto Moerbeek wrote: > On Tue, Jul 12, 2011 at 05:52:09PM +0200, Otto Moerbeek wrote: > > > Hi, > > > > The diff below implements utrace(2), a syscall to introduce data into > > a ktrace stream from a userland program. > > > > The interface is taken from netbsd, freebsd also has a utrace(2) > > syscall, but lacks the label argument. > > > > You could uise this as a debugging aid, to get tarce information > > intermixed with sysclal info, or set more specific tracepoint and only > > see the utrace records. > > > > Do we want this? If so, this should be reviewed and tested. And a man > > page for utrace(2) should be written. > > > > Output of utrace("It is I", "some data", 10) looks like: > > > > 24413 a.out CALL utrace(0x500a09,0x5009ff,0xa) > > 24413 a.out USER It is I: 10 bytes > > "some data\0" > > 24413 a.out RET utrace 0 > > > new diff, with comments incorporated and a manpage. Since the > utrace(2) syscall always exists now, I've put it in sys_generic.c. Is > that a right place?
New diff, the man page comments made me check a few things in there, and then I saw the error values in the code and man page were not corresponding. Copy paste from netbsd without checking is not a valid programming methodology. Here's an updated diff. -Otto Index: lib/libc/sys/Makefile.inc =================================================================== RCS file: /cvs/src/lib/libc/sys/Makefile.inc,v retrieving revision 1.92 diff -u -p -r1.92 Makefile.inc --- lib/libc/sys/Makefile.inc 3 Jul 2010 04:44:51 -0000 1.92 +++ lib/libc/sys/Makefile.inc 18 Jul 2011 12:16:24 -0000 @@ -64,7 +64,7 @@ ASM= accept.o access.o acct.o adjfreq.o setuid.o shmat.o shmctl.o shmdt.o shmget.o shutdown.o sigaction.o \ sigaltstack.o socket.o socketpair.o stat.o statfs.o swapctl.o \ symlink.o sync.o sysarch.o umask.o unlink.o unmount.o \ - utimes.o wait4.o write.o writev.o nnpfspioctl.o __semctl.o \ + utimes.o utrace.o wait4.o write.o writev.o nnpfspioctl.o __semctl.o \ __syscall.o __sysctl.o __getcwd.o sched_yield.o getthrid.o \ thrsleep.o thrwakeup.o threxit.o thrsigdivert.o \ setrtable.o getrtable.o @@ -233,7 +233,7 @@ MAN+= accept.2 access.2 acct.2 adjfreq.2 shutdown.2 sigaction.2 sigaltstack.2 sigpending.2 sigprocmask.2 \ sigreturn.2 sigstack.2 sigsuspend.2 socket.2 socketpair.2 stat.2 \ statfs.2 swapctl.2 symlink.2 sync.2 sysarch.2 syscall.2 truncate.2 \ - umask.2 unlink.2 utimes.2 vfork.2 wait.2 write.2 + umask.2 unlink.2 utimes.2 utrace.2 vfork.2 wait.2 write.2 MAN+= msgctl.2 shmctl.2 shmat.2 semop.2 semget.2 semctl.2 msgsnd.2 msgrcv.2 \ msgget.2 shmget.2 Index: lib/libc/sys/ktrace.2 =================================================================== RCS file: /cvs/src/lib/libc/sys/ktrace.2,v retrieving revision 1.20 diff -u -p -r1.20 ktrace.2 --- lib/libc/sys/ktrace.2 8 Jul 2011 19:30:32 -0000 1.20 +++ lib/libc/sys/ktrace.2 18 Jul 2011 12:16:24 -0000 @@ -94,6 +94,8 @@ generate much output). .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_USER Trace user data coming from +.Xr utrace 2 .It Dv KTRFAC_INHERIT Inherit tracing to future children. .El .Pp @@ -174,7 +176,8 @@ No process can be found corresponding to .El .Sh SEE ALSO .Xr kdump 1 , -.Xr ktrace 1 +.Xr ktrace 1 , +.Xr utrace 2 .Sh HISTORY A .Fn ktrace Index: lib/libc/sys/utrace.2 =================================================================== RCS file: lib/libc/sys/utrace.2 diff -N lib/libc/sys/utrace.2 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/sys/utrace.2 18 Jul 2011 12:16:24 -0000 @@ -0,0 +1,88 @@ +.\" $OpenBSD: utrace.2,v 1.13 2008/05/02 18:38:32 martin Exp $ +.\" $NetBSD: utrace.2,v 1.13 2008/05/02 18:38:32 martin Exp $ +.\" +.\" Copyright (c) 2000 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Gregory McGarry <g.mcga...@ieee.org>. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd $Mdocdate$ +.Dt UTRACE 2 +.Os +.Sh NAME +.Nm utrace +.Nd insert user record in ktrace log +.Sh SYNOPSIS +.In sys/types.h +.In sys/param.h +.In sys/uio.h +.In sys/ktrace.h +.Ft int +.Fn utrace "const char *label" "void *addr" "size_t len" +.Sh DESCRIPTION +Adds a record to the process trace with information supplied by the user. +The record is identified by +.Fa label +and contains +.Fa len +bytes from memory pointed to by +.Fa addr . +This call only has an effect if the calling process is being traced. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ENOSYS +The currently running kernel was compiled without +.Xr ktrace 2 +support (option KTRACE). +.It Bq Er ENAMETOOLONG +The length of the +.Fa label +string was longer than +.Dv KTR_USER_MAXIDLEN\-1 . +.It Bq Er EINVAL +The specified data length +.Fa len +was bigger than +.Dv KTR_USER_MAXLEN . +.El +.Sh SEE ALSO +.Xr kdump 1 , +.Xr ktrace 1 , +.Xr ktrace 2 , +.Xr options 4 +.Sh HISTORY +The +.Fn utrace +system call first appeared in +.Fx 2.2 . +It was added to +.Ox +in +.Ox 5.0 . +The +.Fa label +argument is an extension. Index: sys/kern/init_sysent.c =================================================================== RCS file: /cvs/src/sys/kern/init_sysent.c,v retrieving revision 1.129 diff -u -p -r1.129 init_sysent.c --- sys/kern/init_sysent.c 9 Jul 2011 05:46:58 -0000 1.129 +++ sys/kern/init_sysent.c 18 Jul 2011 12:16:29 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: init_sysent.c,v 1.129 2011/07/09 05:46:58 matthew Exp $ */ +/* $OpenBSD$ */ /* * System call switch table. @@ -785,5 +785,7 @@ struct sysent sysent[] = { sys_unlinkat }, /* 325 = unlinkat */ { 4, s(struct sys_utimensat_args), 0, sys_utimensat }, /* 326 = utimensat */ + { 3, s(struct sys_utrace_args), 0, + sys_utrace }, /* 327 = utrace */ }; Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /cvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.54 diff -u -p -r1.54 kern_ktrace.c --- sys/kern/kern_ktrace.c 11 Jul 2011 15:40:47 -0000 1.54 +++ sys/kern/kern_ktrace.c 18 Jul 2011 12:16:29 -0000 @@ -297,6 +297,39 @@ ktrstruct(struct proc *p, const char *na p->p_traceflag &= ~KTRFAC_ACTIVE; } +int +ktruser(struct proc *p, const char *id, void *addr, size_t len) +{ + struct ktr_header kth; + struct ktr_user *ktp; + int error; + + if (!KTRPOINT(p, KTR_USER)) + return (0); + if (len > KTR_USER_MAXLEN) + return EINVAL; + + p->p_traceflag |= KTRFAC_ACTIVE; + ktrinitheader(&kth, p, KTR_USER); + ktp = malloc(sizeof(*ktp) + len, M_TEMP, M_WAITOK); + bzero(ktp->ktr_id, KTR_USER_MAXIDLEN); + error = copyinstr(id, ktp->ktr_id, KTR_USER_MAXIDLEN, NULL); + if (error) + goto out; + + error = copyin(addr, (void *)(ktp + 1), len); + if (error) + goto out; + kth.ktr_buf = (void *)ktp; + kth.ktr_len = sizeof(*ktp) + len; + ktrwrite(p, &kth); +out: + free(ktp, M_TEMP); + p->p_traceflag &= ~KTRFAC_ACTIVE; + return (error); +} + + /* Interface and common routines */ /* Index: sys/kern/sys_generic.c =================================================================== RCS file: /cvs/src/sys/kern/sys_generic.c,v retrieving revision 1.72 diff -u -p -r1.72 sys_generic.c --- sys/kern/sys_generic.c 19 Dec 2010 19:54:46 -0000 1.72 +++ sys/kern/sys_generic.c 18 Jul 2011 12:16:29 -0000 @@ -884,3 +884,25 @@ bad: free(pl, M_TEMP); return (error); } + + +/* + * utrace system call + */ +/* ARGSUSED */ +int +sys_utrace(struct proc *curp, void *v, register_t *retval) +{ +#ifdef KTRACE + struct sys_utrace_args /* { + syscallarg(const char *) label; + syscallarg(void *) addr; + syscallarg(size_t) len; + } */ *uap = v; + return (ktruser(curp, SCARG(uap, label), SCARG(uap, addr), + SCARG(uap, len))); +#else + return (ENOSYS); +#endif +} + Index: sys/kern/syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/syscalls.c,v retrieving revision 1.130 diff -u -p -r1.130 syscalls.c --- sys/kern/syscalls.c 9 Jul 2011 05:46:58 -0000 1.130 +++ sys/kern/syscalls.c 18 Jul 2011 12:16:29 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: syscalls.c,v 1.130 2011/07/09 05:46:58 matthew Exp $ */ +/* $OpenBSD$ */ /* * System call names. @@ -409,4 +409,5 @@ char *syscallnames[] = { "symlinkat", /* 324 = symlinkat */ "unlinkat", /* 325 = unlinkat */ "utimensat", /* 326 = utimensat */ + "utrace", /* 327 = utrace */ }; Index: sys/kern/syscalls.master =================================================================== RCS file: /cvs/src/sys/kern/syscalls.master,v retrieving revision 1.117 diff -u -p -r1.117 syscalls.master --- sys/kern/syscalls.master 9 Jul 2011 05:46:26 -0000 1.117 +++ sys/kern/syscalls.master 18 Jul 2011 12:16:29 -0000 @@ -572,3 +572,5 @@ int flag); } 326 STD { int sys_utimensat(int fd, const char *path, \ const struct timespec *times, int flag); } +327 STD { int sys_utrace(const char *label, void *addr, \ + size_t len); } Index: sys/sys/ktrace.h =================================================================== RCS file: /cvs/src/sys/sys/ktrace.h,v retrieving revision 1.11 diff -u -p -r1.11 ktrace.h --- sys/sys/ktrace.h 8 Jul 2011 19:28:38 -0000 1.11 +++ sys/sys/ktrace.h 18 Jul 2011 12:16:29 -0000 @@ -146,6 +146,19 @@ struct sockaddr; struct stat; /* + * KTR_USER - user record + */ +#define KTR_USER 9 +#define KTR_USER_MAXIDLEN 20 +#define KTR_USER_MAXLEN 2048 /* maximum length of passed data */ +struct ktr_user { + char ktr_id[KTR_USER_MAXIDLEN]; /* string id of caller */ + /* + * Followed by ktr_len - sizeof(struct ktr_user) of user data. + */ +}; + +/* * kernel trace points (in p_traceflag) */ #define KTRFAC_MASK 0x00ffffff @@ -157,6 +170,7 @@ struct stat; #define KTRFAC_CSW (1<<KTR_CSW) #define KTRFAC_EMUL (1<<KTR_EMUL) #define KTRFAC_STRUCT (1<<KTR_STRUCT) +#define KTRFAC_USER (1<<KTR_USER) /* * trace flags (also in p_traceflags) @@ -171,6 +185,7 @@ struct stat; __BEGIN_DECLS int ktrace(const char *, int, int, pid_t); +int utrace(const char *, void *, size_t); __END_DECLS #else @@ -182,6 +197,8 @@ void ktrnamei(struct proc *, char *); void ktrpsig(struct proc *, int, sig_t, int, int, siginfo_t *); void ktrsyscall(struct proc *, register_t, size_t, register_t []); void ktrsysret(struct proc *, register_t, int, register_t); +void ktr_kuser(const char *, void *, size_t); +int ktruser(struct proc *, const char *, void *, size_t); void ktrsettracevnode(struct proc *, struct vnode *); Index: sys/sys/syscall.h =================================================================== RCS file: /cvs/src/sys/sys/syscall.h,v retrieving revision 1.129 diff -u -p -r1.129 syscall.h --- sys/sys/syscall.h 9 Jul 2011 05:46:58 -0000 1.129 +++ sys/sys/syscall.h 18 Jul 2011 12:16:30 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.129 2011/07/09 05:46:58 matthew Exp $ */ +/* $OpenBSD$ */ /* * System call numbers. @@ -670,4 +670,7 @@ /* syscall: "utimensat" ret: "int" args: "int" "const char *" "const struct timespec *" "int" */ #define SYS_utimensat 326 -#define SYS_MAXSYSCALL 327 +/* syscall: "utrace" ret: "int" args: "const char *" "void *" "size_t" */ +#define SYS_utrace 327 + +#define SYS_MAXSYSCALL 328 Index: sys/sys/syscallargs.h =================================================================== RCS file: /cvs/src/sys/sys/syscallargs.h,v retrieving revision 1.131 diff -u -p -r1.131 syscallargs.h --- sys/sys/syscallargs.h 9 Jul 2011 05:46:58 -0000 1.131 +++ sys/sys/syscallargs.h 18 Jul 2011 12:16:30 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: syscallargs.h,v 1.131 2011/07/09 05:46:58 matthew Exp $ */ +/* $OpenBSD$ */ /* * System call argument lists. @@ -1040,6 +1040,12 @@ struct sys_utimensat_args { syscallarg(int) flag; }; +struct sys_utrace_args { + syscallarg(const char *) label; + syscallarg(void *) addr; + syscallarg(size_t) len; +}; + /* * System call prototypes. */ @@ -1293,3 +1299,4 @@ int sys_renameat(struct proc *, void *, int sys_symlinkat(struct proc *, void *, register_t *); int sys_unlinkat(struct proc *, void *, register_t *); int sys_utimensat(struct proc *, void *, register_t *); +int sys_utrace(struct proc *, void *, register_t *); Index: usr.bin/kdump/kdump.1 =================================================================== RCS file: /cvs/src/usr.bin/kdump/kdump.1,v retrieving revision 1.20 diff -u -p -r1.20 kdump.1 --- usr.bin/kdump/kdump.1 9 Jul 2011 15:43:38 -0000 1.20 +++ usr.bin/kdump/kdump.1 18 Jul 2011 12:16:30 -0000 @@ -43,7 +43,7 @@ .Op Fl f Ar file .Op Fl m Ar maxdata .Op Fl p Ar pid -.Op Fl t Op ceinsw +.Op Fl t Op ceinstuw .Ek .Sh DESCRIPTION .Nm @@ -101,7 +101,7 @@ When decoding STRU records, display stru GIDs, dates etc. symbolically instead of numerically. .It Fl T Display absolute timestamps for each entry (seconds since the Epoch). -.It Fl t Op ceinstw +.It Fl t Op ceinstuw Selects which tracepoints to display. See the .Fl t Index: usr.bin/kdump/kdump.c =================================================================== RCS file: /cvs/src/usr.bin/kdump/kdump.c,v retrieving revision 1.60 diff -u -p -r1.60 kdump.c --- usr.bin/kdump/kdump.c 17 Jul 2011 07:49:34 -0000 1.60 +++ usr.bin/kdump/kdump.c 18 Jul 2011 12:16:30 -0000 @@ -141,6 +141,7 @@ 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 ktruser(struct ktr_user *, size_t); static void setemul(const char *); static void usage(void); @@ -260,6 +261,9 @@ main(int argc, char *argv[]) case KTR_STRUCT: ktrstruct(m, ktrlen); break; + case KTR_USER: + ktruser(m, ktrlen); + break; } if (tail) (void)fflush(stdout); @@ -343,6 +347,9 @@ dumpheader(struct ktr_header *kth) case KTR_STRUCT: type = "STRU"; break; + case KTR_USER: + type = "USER"; + break; default: (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)", kth->ktr_type); @@ -808,12 +815,10 @@ ktremul(char *cp, size_t len) } static void -ktrgenio(struct ktr_genio *ktr, size_t len) +showbuf(unsigned char *dp, size_t datalen) { - unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); int i, j; - size_t datalen = len - sizeof(struct ktr_genio); - static int screenwidth = 0; + static int screenwidth; int col = 0, width, bpl; unsigned char visbuf[5], *cp, c; @@ -826,14 +831,6 @@ ktrgenio(struct ktr_genio *ktr, size_t l else screenwidth = 80; } - printf("fd %d %s %zu bytes\n", ktr->ktr_fd, - ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); - if (maxdata == 0) - return; - if (datalen > maxdata) - datalen = maxdata; - if (iohex && !datalen) - return; if (iohex == 1) { putchar('\t'); col = 8; @@ -916,6 +913,23 @@ ktrgenio(struct ktr_genio *ktr, size_t l } static void +ktrgenio(struct ktr_genio *ktr, size_t len) +{ + unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); + size_t datalen = len - sizeof(struct ktr_genio); + + printf("fd %d %s %zu bytes\n", ktr->ktr_fd, + ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); + if (maxdata == 0) + return; + if (datalen > maxdata) + datalen = maxdata; + if (iohex && !datalen) + return; + showbuf(dp, datalen); +} + +static void ktrpsig(struct ktr_psig *psig) { (void)printf("SIG%s ", sys_signame[psig->signo]); @@ -945,8 +959,6 @@ ktrcsw(struct ktr_csw *cs) cs->user ? "user" : "kernel"); } - - void ktrsockaddr(struct sockaddr *sa) { @@ -1137,13 +1149,22 @@ invalid: } static void +ktruser(struct ktr_user *usr, size_t len) +{ + len -= sizeof(struct ktr_user); + printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); + printf(" %zu bytes\n", len); + showbuf((unsigned char *)(usr + 1), len); +} + +static void usage(void) { extern char *__progname; fprintf(stderr, "usage: %s " "[-dlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n" - "%*s[-t [ceinsw]]\n", + "%*s[-t [ceinstuw]]\n", __progname, (int)(sizeof("usage: ") + strlen(__progname)), ""); exit(1); } Index: usr.bin/ktrace/ktrace.1 =================================================================== RCS file: /cvs/src/usr.bin/ktrace/ktrace.1,v retrieving revision 1.22 diff -u -p -r1.22 ktrace.1 --- usr.bin/ktrace/ktrace.1 8 Jul 2011 20:37:18 -0000 1.22 +++ usr.bin/ktrace/ktrace.1 18 Jul 2011 12:16:30 -0000 @@ -109,8 +109,9 @@ The default flags are .Cm i , .Cm n , .Cm s , +.Cm t , and -.Cm t . +.Cm u . The following table equates the letters with the tracepoints: .Pp .Bl -tag -width flag -offset indent -compact @@ -126,6 +127,9 @@ trace namei translations trace signal processing .It Cm t trace various structures +.It Cm u +trace user data coming from +.Xr utrace 2 .It Cm w trace context switch points .It Cm + @@ -177,7 +181,8 @@ Disable tracing of all processes owned b .Dl $ ktrace -C .Sh SEE ALSO .Xr kdump 1 , -.Xr ktrace 2 +.Xr ktrace 2 , +.Xr utrace 2 .Sh HISTORY The .Nm ktrace Index: usr.bin/ktrace/ktrace.h =================================================================== RCS file: /cvs/src/usr.bin/ktrace/ktrace.h,v retrieving revision 1.4 diff -u -p -r1.4 ktrace.h --- usr.bin/ktrace/ktrace.h 8 Jul 2011 19:29:44 -0000 1.4 +++ usr.bin/ktrace/ktrace.h 18 Jul 2011 12:16:30 -0000 @@ -31,7 +31,8 @@ */ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ - KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_STRUCT) + KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_STRUCT | \ + KTRFAC_USER) #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.7 diff -u -p -r1.7 subr.c --- usr.bin/ktrace/subr.c 8 Jul 2011 19:29:44 -0000 1.7 +++ usr.bin/ktrace/subr.c 18 Jul 2011 12:16:30 -0000 @@ -71,6 +71,9 @@ getpoints(s) case 't': facs |= KTRFAC_STRUCT; break; + case 'u': + facs |= KTRFAC_USER; + break; case '+': facs |= DEF_POINTS; break;