Module Name: src Committed By: kamil Date: Wed May 1 21:57:35 UTC 2019
Modified Files: src/sys/kern: kern_lwp.c sys_lwp.c Log Message: Correct passing debugger related events for LWP create and exit Add MI toplevel startlwp function. Switch all userland LWPs to go through lwp_create using a shared mi_startlwp() function between all MD ABIs. Add debugger related event handling in mi_startlwp() and continue with standard p->p_emul->e_startlwp at the end of this routine. Use eventswitch() to notify the event of LWP exit in lwp_exit(). ATF ptrace(2) tests signal9 and signal10 now pass. To generate a diff of this commit: cvs rdiff -u -r1.197 -r1.198 src/sys/kern/kern_lwp.c cvs rdiff -u -r1.63 -r1.64 src/sys/kern/sys_lwp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.197 src/sys/kern/kern_lwp.c:1.198 --- src/sys/kern/kern_lwp.c:1.197 Fri Apr 19 01:52:55 2019 +++ src/sys/kern/kern_lwp.c Wed May 1 21:57:34 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.197 2019/04/19 01:52:55 ozaki-r Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.198 2019/05/01 21:57:34 kamil Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -211,7 +211,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.197 2019/04/19 01:52:55 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.198 2019/05/01 21:57:34 kamil Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -969,24 +969,6 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_ if (p2->p_emul->e_lwp_fork) (*p2->p_emul->e_lwp_fork)(l1, l2); - /* If the process is traced, report lwp creation to a debugger */ - if ((p2->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE|PSL_SYSCALL)) == - (PSL_TRACED|PSL_TRACELWP_CREATE)) { - ksiginfo_t ksi; - - /* Tracing */ - KASSERT((l2->l_flag & LW_SYSTEM) == 0); - - p2->p_lwp_created = l2->l_lid; - - KSI_INIT_EMPTY(&ksi); - ksi.ksi_signo = SIGTRAP; - ksi.ksi_code = TRAP_LWP; - mutex_enter(proc_lock); - kpsignal(p2, &ksi, NULL); - mutex_exit(proc_lock); - } - return (0); } @@ -1050,24 +1032,6 @@ lwp_exit(struct lwp *l) */ LOCKDEBUG_BARRIER(&kernel_lock, 0); - /* If the process is traced, report lwp termination to a debugger */ - if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_EXIT|PSL_SYSCALL)) == - (PSL_TRACED|PSL_TRACELWP_EXIT)) { - ksiginfo_t ksi; - - /* Tracing */ - KASSERT((l->l_flag & LW_SYSTEM) == 0); - - p->p_lwp_exited = l->l_lid; - - KSI_INIT_EMPTY(&ksi); - ksi.ksi_signo = SIGTRAP; - ksi.ksi_code = TRAP_LWP; - mutex_enter(proc_lock); - kpsignal(p, &ksi, NULL); - mutex_exit(proc_lock); - } - /* * If we are the last live LWP in a process, we need to exit the * entire process. We do so with an exit status of zero, because @@ -1108,10 +1072,23 @@ lwp_exit(struct lwp *l) callout_destroy(&l->l_timeout_ch); /* + * If traced, report LWP exit event to the debugger. + * * Remove the LWP from the global list. * Free its LID from the PID namespace if needed. */ mutex_enter(proc_lock); + + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_EXIT|PSL_SYSCALL)) == + (PSL_TRACED|PSL_TRACELWP_EXIT)) { + mutex_enter(p->p_lock); + p->p_lwp_exited = l->l_lid; + eventswitch(SIGTRAP, TRAP_LWP); + // XXX ktrpoint(KTR_PSIG) + mutex_exit(p->p_lock); + mutex_enter(proc_lock); + } + LIST_REMOVE(l, l_list); if ((l->l_pflag & LP_PIDLID) != 0 && l->l_lid != p->p_pid) { proc_free_pid(l->l_lid); Index: src/sys/kern/sys_lwp.c diff -u src/sys/kern/sys_lwp.c:1.63 src/sys/kern/sys_lwp.c:1.64 --- src/sys/kern/sys_lwp.c:1.63 Tue Jan 30 07:52:23 2018 +++ src/sys/kern/sys_lwp.c Wed May 1 21:57:34 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_lwp.c,v 1.63 2018/01/30 07:52:23 ozaki-r Exp $ */ +/* $NetBSD: sys_lwp.c,v 1.64 2019/05/01 21:57:34 kamil Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.63 2018/01/30 07:52:23 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.64 2019/05/01 21:57:34 kamil Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -69,6 +69,34 @@ lwp_sys_init(void) sleeptab_init(&lwp_park_tab); } +static void +mi_startlwp(void *arg) +{ + struct lwp *l = curlwp; + struct proc *p = l->l_proc; + + /* If the process is traced, report lwp creation to a debugger */ + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE|PSL_SYSCALL)) == + (PSL_TRACED|PSL_TRACELWP_CREATE)) { + /* Paranoid check */ + mutex_enter(proc_lock); + if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_CREATE|PSL_SYSCALL)) != + (PSL_TRACED|PSL_TRACELWP_CREATE)) { + mutex_exit(proc_lock); + goto my_tracer_is_gone; + } + + mutex_enter(p->p_lock); + p->p_lwp_created = l->l_lid; + eventswitch(SIGTRAP, TRAP_LWP); + // XXX ktrpoint(KTR_PSIG) + mutex_exit(p->p_lock); + } + +my_tracer_is_gone: + (p->p_emul->e_startlwp)(arg); +} + int do_lwp_create(lwp_t *l, void *arg, u_long flags, lwpid_t *new_lwp, const sigset_t *sigmask, const stack_t *sigstk) @@ -86,7 +114,7 @@ do_lwp_create(lwp_t *l, void *arg, u_lon return ENOMEM; error = lwp_create(l, p, uaddr, flags & LWP_DETACHED, NULL, 0, - p->p_emul->e_startlwp, arg, &l2, l->l_class, sigmask, &SS_INIT); + mi_startlwp, arg, &l2, l->l_class, sigmask, &SS_INIT); if (__predict_false(error)) { uvm_uarea_free(uaddr); return error;