As per http://research.swtch.com/macpprof
We deliver all prof signals to the main thread, which is unlikely to result in accurate profiling info. I think the diff below fixes things. Index: kern/kern_clock.c =================================================================== RCS file: /cvs/src/sys/kern/kern_clock.c,v retrieving revision 1.81 diff -u -p -r1.81 kern_clock.c --- kern/kern_clock.c 24 Apr 2013 17:29:02 -0000 1.81 +++ kern/kern_clock.c 16 Aug 2013 05:57:27 -0000 @@ -173,9 +173,9 @@ virttimer_trampoline(void *v) void proftimer_trampoline(void *v) { - struct process *pr = v; + struct proc *p = v; - psignal(pr->ps_mainproc, SIGPROF); + psignal(p, SIGPROF); } /* @@ -200,7 +200,7 @@ hardclock(struct clockframe *frame) timeout_add(&pr->ps_virt_to, 1); if (timerisset(&pr->ps_timer[ITIMER_PROF].it_value) && itimerdecr(&pr->ps_timer[ITIMER_PROF], tick) == 0) - timeout_add(&pr->ps_prof_to, 1); + timeout_add(&p->p_prof_to, 1); } /* Index: kern/kern_exit.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exit.c,v retrieving revision 1.125 diff -u -p -r1.125 kern_exit.c --- kern/kern_exit.c 5 Jun 2013 00:53:26 -0000 1.125 +++ kern/kern_exit.c 16 Aug 2013 05:57:27 -0000 @@ -183,10 +183,10 @@ exit1(struct proc *p, int rv, int flags) */ fdfree(p); + timeout_del(&p->p_prof_to); if ((p->p_flag & P_THREAD) == 0) { timeout_del(&pr->ps_realit_to); timeout_del(&pr->ps_virt_to); - timeout_del(&pr->ps_prof_to); #ifdef SYSVSEM semexit(pr); #endif Index: kern/kern_fork.c =================================================================== RCS file: /cvs/src/sys/kern/kern_fork.c,v retrieving revision 1.152 diff -u -p -r1.152 kern_fork.c --- kern/kern_fork.c 11 Jun 2013 13:00:31 -0000 1.152 +++ kern/kern_fork.c 16 Aug 2013 05:57:27 -0000 @@ -209,7 +209,6 @@ process_new(struct proc *p, struct proce timeout_set(&pr->ps_realit_to, realitexpire, pr); timeout_set(&pr->ps_virt_to, virttimer_trampoline, pr); - timeout_set(&pr->ps_prof_to, proftimer_trampoline, pr); pr->ps_flags = parent->ps_flags & (PS_SUGID | PS_SUGIDEXEC); if (parent->ps_session->s_ttyvp != NULL && @@ -342,6 +341,7 @@ fork1(struct proc *curp, int exitsig, in * Initialize the timeouts. */ timeout_set(&p->p_sleep_to, endtsleep, p); + timeout_set(&p->p_prof_to, proftimer_trampoline, p); /* * Duplicate sub-structures as needed. Index: kern/kern_time.c =================================================================== RCS file: /cvs/src/sys/kern/kern_time.c,v retrieving revision 1.80 diff -u -p -r1.80 kern_time.c --- kern/kern_time.c 17 Jun 2013 19:11:54 -0000 1.80 +++ kern/kern_time.c 16 Aug 2013 05:57:27 -0000 @@ -568,7 +568,7 @@ sys_setitimer(struct proc *p, void *v, r if (which == ITIMER_VIRTUAL) timeout_del(&pr->ps_virt_to); if (which == ITIMER_PROF) - timeout_del(&pr->ps_prof_to); + timeout_del(&p->p_prof_to); splx(s); } Index: sys/proc.h =================================================================== RCS file: /cvs/src/sys/sys/proc.h,v retrieving revision 1.168 diff -u -p -r1.168 proc.h --- sys/proc.h 6 Jun 2013 13:09:37 -0000 1.168 +++ sys/proc.h 16 Aug 2013 05:57:28 -0000 @@ -210,7 +210,6 @@ struct process { struct timespec ps_start; /* starting time. */ struct timeout ps_realit_to; /* real-time itimer trampoline. */ struct timeout ps_virt_to; /* virtual itimer trampoline. */ - struct timeout ps_prof_to; /* prof itimer trampoline. */ int ps_refcnt; /* Number of references. */ }; @@ -337,6 +336,7 @@ struct proc { /* End area that is copied on creation. */ #define p_endcopy p_addr + struct timeout p_prof_to; /* prof itimer trampoline. */ struct user *p_addr; /* Kernel virtual addr of u-area */ struct mdproc p_md; /* Any machine-dependent fields. */