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;

Reply via email to