I recently had to debug something not working for netbsd32 emulation and
found that signals created bogus (64bit) ktrace records.

I came up with the attached patch which seems to work but is a bit ugly
and intrusive. It may not be fully modular and is missing an indirection
from the original ktrpsig -> ktrpsig(), so it is not checking ktrace_on.
I am not sure we can ever get to this code w/o ktrace_on.

I wonder if we should instead of the emulation redirection check
(#ifdef'd properly) for a 32bit process and then hard-coded test against
netbsd32 emulation. No other emulation would ever want to interfere with
the netbsd-specific kte records - or do I miss something?


Martin
P.S.: sendmsg also creates 64bit records, but that is pretty intrusive to
fix too, leaving that for another day.
Index: sys/ktrace.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ktrace.h,v
retrieving revision 1.63
diff -u -p -r1.63 ktrace.h
--- sys/ktrace.h        19 Mar 2016 17:04:12 -0000      1.63
+++ sys/ktrace.h        8 Sep 2016 15:16:01 -0000
@@ -432,6 +432,15 @@ ktrexecfd(int fd, u_int dtype)
                ktr_execfd(fd, dtype);
 }
 
+struct ktrace_entry;
+int    ktealloc(struct ktrace_entry **, void **, lwp_t *, int, size_t);
+void   ktesethdrlen(struct ktrace_entry *, size_t);
+void   ktraddentry(lwp_t *, struct ktrace_entry *, int);
+/* Flags for ktraddentry (3rd arg) */
+#define        KTA_NOWAIT              0x0000
+#define        KTA_WAITOK              0x0001
+#define        KTA_LARGE               0x0002
+
 #endif /* !_KERNEL */
 
 #endif /* _SYS_KTRACE_H_ */
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.331
diff -u -p -r1.331 proc.h
--- sys/proc.h  10 Jun 2016 23:24:33 -0000      1.331
+++ sys/proc.h  8 Sep 2016 15:16:01 -0000
@@ -192,6 +192,10 @@ struct emul {
        void            (*e_dtrace_syscall)(uint32_t, register_t,
                            const struct sysent *, const void *,
                            const register_t *, int);
+
+       /* Emulation specific support for ktracing signal posts */
+       void            (*e_ktrpsig)(int, sig_t, const sigset_t *,
+                           const ksiginfo_t *);
 };
 
 /*
Index: kern/kern_ktrace.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.167
diff -u -p -r1.167 kern_ktrace.c
--- kern/kern_ktrace.c  7 Jul 2016 06:55:43 -0000       1.167
+++ kern/kern_ktrace.c  8 Sep 2016 15:16:01 -0000
@@ -126,8 +126,6 @@ struct ktr_desc {
        kcondvar_t ktd_cv;
 };
 
-static int     ktealloc(struct ktrace_entry **, void **, lwp_t *, int,
-                        size_t);
 static void    ktrwrite(struct ktr_desc *, struct ktrace_entry *);
 static int     ktrops(lwp_t *, struct proc *, int, int,
                    struct ktr_desc *);
@@ -142,11 +140,6 @@ static struct ktr_desc *
                ktd_lookup(file_t *);
 static void    ktdrel(struct ktr_desc *);
 static void    ktdref(struct ktr_desc *);
-static void    ktraddentry(lwp_t *, struct ktrace_entry *, int);
-/* Flags for ktraddentry (3rd arg) */
-#define        KTA_NOWAIT              0x0000
-#define        KTA_WAITOK              0x0001
-#define        KTA_LARGE               0x0002
 static void    ktefree(struct ktrace_entry *);
 static void    ktd_logerrl(struct ktr_desc *, int);
 static void    ktrace_thread(void *);
@@ -538,6 +531,12 @@ ktealloc(struct ktrace_entry **ktep, voi
 }
 
 void
+ktesethdrlen(struct ktrace_entry *kte, size_t l)
+{      
+       kte->kte_kth.ktr_len = l;
+}
+
+void
 ktr_syscall(register_t code, const register_t args[], int narg)
 {
        lwp_t *l = curlwp;
Index: kern/kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.329
diff -u -p -r1.329 kern_sig.c
--- kern/kern_sig.c     21 Aug 2016 15:24:17 -0000      1.329
+++ kern/kern_sig.c     8 Sep 2016 15:16:01 -0000
@@ -913,8 +913,14 @@ trapsignal(struct lwp *l, ksiginfo_t *ks
                kpsendsig(l, ksi, mask);
                mutex_exit(p->p_lock);
                if (ktrpoint(KTR_PSIG)) {
-                       ktrpsig(signo, SIGACTION_PS(ps, signo).sa_handler,
-                           mask, ksi);
+                       if (__predict_false(p->p_emul->e_ktrpsig))
+                               p->p_emul->e_ktrpsig(signo,
+                                   SIGACTION_PS(ps, signo).sa_handler,
+                                   mask, ksi);
+                       else
+                               ktrpsig(signo, 
+                                   SIGACTION_PS(ps, signo).sa_handler,
+                                   mask, ksi);
                }
        } else {
                /* XXX for core dump/debugger */
@@ -1860,7 +1866,11 @@ postsig(int signo)
 
        if (ktrpoint(KTR_PSIG)) {
                mutex_exit(p->p_lock);
-               ktrpsig(signo, action, returnmask, &ksi);
+               if (__predict_false(p->p_emul->e_ktrpsig))
+                       p->p_emul->e_ktrpsig(signo, action,
+                           returnmask, &ksi);
+               else
+                       ktrpsig(signo, action, returnmask, &ksi);
                mutex_enter(p->p_lock);
        }
 
Index: compat/netbsd32/netbsd32.h
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32.h,v
retrieving revision 1.109
diff -u -p -r1.109 netbsd32.h
--- compat/netbsd32/netbsd32.h  26 Nov 2015 13:15:34 -0000      1.109
+++ compat/netbsd32/netbsd32.h  8 Sep 2016 15:16:01 -0000
@@ -1105,6 +1105,7 @@ void netbsd32_adjust_limits(struct proc 
 
 void   netbsd32_si_to_si32(siginfo32_t *, const siginfo_t *);
 void   netbsd32_ksi32_to_ksi(struct _ksiginfo *si, const struct __ksiginfo32 
*si32);
+void   netbsd32_ksi_to_ksi32(struct __ksiginfo32 *si32, const struct _ksiginfo 
*si);
 
 
 void   startlwp32(void *);
Index: compat/netbsd32/netbsd32_netbsd.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.200
diff -u -p -r1.200 netbsd32_netbsd.c
--- compat/netbsd32/netbsd32_netbsd.c   13 May 2016 16:54:36 -0000      1.200
+++ compat/netbsd32/netbsd32_netbsd.c   8 Sep 2016 15:16:01 -0000
@@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_net
 #include <sys/dirent.h>
 #include <sys/quotactl.h>
 #include <sys/kauth.h>
+#include <sys/ktrace.h>
 #include <sys/vfs_syscalls.h>
 
 #include <uvm/uvm_extern.h>
@@ -103,6 +104,8 @@ void netbsd32_syscall_intern(struct proc
 void syscall(void);
 #endif
 
+void netbsd32_ktrpsig(int, sig_t, const sigset_t *, const ksiginfo_t *);
+
 #define LIMITCHECK(a, b) ((a) != RLIM_INFINITY && (a) > (b))
 
 #ifdef COMPAT_16
@@ -162,7 +165,8 @@ struct emul emul_netbsd32 = {
        .e_vm_default_addr =    netbsd32_vm_default_addr,
        .e_usertrap =           NULL,
        .e_ucsize =             sizeof(ucontext32_t),
-       .e_startlwp =           startlwp32
+       .e_startlwp =           startlwp32,
+       .e_ktrpsig =            netbsd32_ktrpsig
 };
 
 /*
@@ -2890,6 +2894,48 @@ netbsd32__pset_bind(struct lwp *l,
        return sys__pset_bind(l, &ua, retval);
 }
 
+struct netbsd32_ktr_psig {
+       int                     signo;
+       netbsd32_pointer_t      action;
+       sigset_t                mask;
+       int                     code;
+       /* and optional siginfo_t */
+};
+
+void
+netbsd32_ktrpsig(int sig, sig_t action, const sigset_t *mask,
+        const ksiginfo_t *ksi)
+{
+       struct ktrace_entry *kte;
+       lwp_t *l = curlwp;
+       struct {
+               struct netbsd32_ktr_psig        kp;
+               siginfo32_t                     si;
+       } *kbuf;
+
+       if (!KTRPOINT(l->l_proc, KTR_PSIG))
+               return;
+
+       if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf)))
+               return;
+
+       kbuf->kp.signo = (char)sig;
+       NETBSD32PTR32(kbuf->kp.action, action);
+       kbuf->kp.mask = *mask;
+
+       if (ksi) {
+               kbuf->kp.code = KSI_TRAPCODE(ksi);
+               (void)memset(&kbuf->si, 0, sizeof(kbuf->si));
+               netbsd32_ksi_to_ksi32(&kbuf->si._info, &ksi->ksi_info);
+               ktesethdrlen(kte, sizeof(*kbuf));
+       } else {
+               kbuf->kp.code = 0;
+               ktesethdrlen(kte, sizeof(struct netbsd32_ktr_psig));
+       }
+
+       ktraddentry(l, kte, KTA_WAITOK);
+}
+
 
 /*
  * MI indirect system call support.
Index: compat/netbsd32/netbsd32_signal.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_signal.c,v
retrieving revision 1.39
diff -u -p -r1.39 netbsd32_signal.c
--- compat/netbsd32/netbsd32_signal.c   20 Jun 2015 19:58:40 -0000      1.39
+++ compat/netbsd32/netbsd32_signal.c   8 Sep 2016 15:16:01 -0000
@@ -221,6 +221,46 @@ netbsd32_ksi32_to_ksi(struct _ksiginfo *
 }
 
 void
+netbsd32_ksi_to_ksi32(struct __ksiginfo32 *si32, const struct _ksiginfo *si)
+{
+       memset(si32, 0, sizeof (*si32));
+       si32->_signo = si->_signo;
+       si32->_code = si->_code;
+       si32->_errno = si->_errno;
+
+       switch (si->_signo) {
+       case SIGILL:
+       case SIGBUS:
+       case SIGSEGV:
+       case SIGFPE:
+       case SIGTRAP:
+               si32->_reason._fault._addr =
+                   NETBSD32PTR32I(si->_reason._fault._addr);
+               si32->_reason._fault._trap = si->_reason._fault._trap;
+               break;
+       case SIGALRM:
+       case SIGVTALRM:
+       case SIGPROF:
+       default:        /* see sigqueue() and kill1() */
+               si32->_reason._rt._pid = si->_reason._rt._pid;
+               si32->_reason._rt._uid = si->_reason._rt._uid;
+               si32->_reason._rt._value.sival_int = 
si->_reason._rt._value.sival_int;
+               break;
+       case SIGCHLD:
+               si32->_reason._child._pid = si->_reason._child._pid;
+               si32->_reason._child._uid = si->_reason._child._uid;
+               si32->_reason._child._utime = si->_reason._child._utime;
+               si32->_reason._child._stime = si->_reason._child._stime;
+               break;
+       case SIGURG:
+       case SIGIO:
+               si32->_reason._poll._band = si->_reason._poll._band;
+               si32->_reason._poll._fd = si->_reason._poll._fd;
+               break;
+       }
+}
+
+void
 netbsd32_si_to_si32(siginfo32_t *si32, const siginfo_t *si)
 {
        memset(si32, 0, sizeof (*si32));

Reply via email to