PERFORCE change 55888 for review

David Xu davidxu at FreeBSD.org
Sun Jun 27 03:04:31 GMT 2004


http://perforce.freebsd.org/chv.cgi?CH=55888

Change 55888 by davidxu at davidxu_alona on 2004/06/27 03:03:35

	Simplify code in trapsignal.
	       Add code to allow signal to be exchanged for trapped thread
	       with debugger. 

Affected files ...

.. //depot/projects/davidxu_ksedbg/src/sys/kern/kern_sig.c#2 edit

Differences ...

==== //depot/projects/davidxu_ksedbg/src/sys/kern/kern_sig.c#2 (text+ko) ====

@@ -1489,23 +1489,16 @@
 		if (td->td_mailbox == NULL)
 			thread_user_enter(p, td);
 		PROC_LOCK(p);
-		if (td->td_mailbox) {
-			SIGDELSET(td->td_sigmask, sig);
-			mtx_lock_spin(&sched_lock);
-			/*
-			 * Force scheduling an upcall, so UTS has chance to
-			 * process the signal before thread runs again in
-			 * userland.
-			 */
-			if (td->td_upcall)
-				td->td_upcall->ku_flags |= KUF_DOUPCALL;
-			mtx_unlock_spin(&sched_lock);
-		} else {
-			/* UTS caused a sync signal */
-			p->p_code = code;	/* XXX for core dump/debugger */
-			p->p_sig = sig;		/* XXX to verify code */
-			sigexit(td, sig);
-		}
+		SIGDELSET(td->td_sigmask, sig);
+		mtx_lock_spin(&sched_lock);
+		/*
+		 * Force scheduling an upcall, so UTS has chance to
+		 * process the signal before thread runs again in
+		 * userland.
+		 */
+		if (td->td_upcall)
+			td->td_upcall->ku_flags |= KUF_DOUPCALL;
+		mtx_unlock_spin(&sched_lock);
 	} else {
 		PROC_LOCK(p);
 	}
@@ -1523,17 +1516,23 @@
 			(*p->p_sysent->sv_sendsig)(
 				ps->ps_sigact[_SIG_IDX(sig)], sig,
 				&td->td_sigmask, code);
-		else {
+		else if (td->td_mailbox == NULL) {
+			mtx_unlock(&ps->ps_mtx);
+			/* UTS caused a sync signal */
+			p->p_code = code;	/* XXX for core dump/debugger */
+			p->p_sig = sig;		/* XXX to verify code */
+			sigexit(td, sig);
+		} else {
 			cpu_thread_siginfo(sig, code, &siginfo);
 			mtx_unlock(&ps->ps_mtx);
+			SIGADDSET(td->td_sigmask, sig);
 			PROC_UNLOCK(p);
 			error = copyout(&siginfo, &td->td_mailbox->tm_syncsig,
 			    sizeof(siginfo));
 			PROC_LOCK(p);
 			/* UTS memory corrupted */
 			if (error)
-				sigexit(td, SIGILL);
-			SIGADDSET(td->td_sigmask, sig);
+				sigexit(td, SIGSEGV);
 			mtx_lock(&ps->ps_mtx);
 		}
 		SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
@@ -2001,27 +2000,57 @@
 	}
 }
 
-void
+int
 ptracestop(struct thread *td, int sig)
 {
 	struct proc *p = td->td_proc;
+	struct thread *td0;
+	int newsig;
 
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
 	    &p->p_mtx.mtx_object, "Stopping for traced signal");
 
+	while (P_SHOULDSTOP(p)) {
+		if (p->p_flag & P_SINGLE_EXIT)
+			return (sig);
+		mtx_lock_spin(&sched_lock);
+		thread_stopped(p);
+		thread_suspend_one(td);
+		PROC_UNLOCK(p);
+		DROP_GIANT();
+		mi_switch(SW_INVOL);
+		mtx_unlock_spin(&sched_lock);
+		PICKUP_GIANT();
+		PROC_LOCK(p);
+	}
 	p->p_xstat = sig;
-	PROC_LOCK(p->p_pptr);
-	psignal(p->p_pptr, SIGCHLD);
-	PROC_UNLOCK(p->p_pptr);
-	stop(p);
+	p->p_xthread = td;
+	p->p_flag |= (P_STOPPED_SIG|P_STOPPED_TRACE);
 	mtx_lock_spin(&sched_lock);
+	FOREACH_THREAD_IN_PROC(p, td0) {
+		if (TD_IS_SLEEPING(td0) &&
+		    (td0->td_flags & TDF_SINTR) &&
+		    !TD_IS_SUSPENDED(td0)) {
+			thread_suspend_one(td0);
+		} else if (td != td0) {
+			td0->td_flags |= TDF_ASTPENDING;
+		}
+	}
+	thread_stopped(p);
 	thread_suspend_one(td);
 	PROC_UNLOCK(p);
 	DROP_GIANT();
 	mi_switch(SW_INVOL);
 	mtx_unlock_spin(&sched_lock);
 	PICKUP_GIANT();
+	PROC_LOCK(p);
+	newsig = p->p_xstat;
+	p->p_xstat = newsig;
+	mtx_lock_spin(&sched_lock);
+	thread_unsuspend(p);
+	mtx_unlock_spin(&sched_lock);
+	return (newsig);
 }
 
 /*
@@ -2043,7 +2072,7 @@
 	struct proc *p;
 	struct sigacts *ps;
 	sigset_t sigpending;
-	int sig, prop;
+	int sig, prop, newsig;
 	struct thread *td0;
 
 	p = td->td_proc;
@@ -2074,6 +2103,8 @@
 		 */
 		if (SIGISMEMBER(ps->ps_sigignore, sig) && (traced == 0)) {
 			SIGDELSET(td->td_siglist, sig);
+			if (td->td_pflags & TDP_SA)
+				SIGADDSET(td->td_sigmask, sig);
 			continue;
 		}
 		if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
@@ -2081,8 +2112,7 @@
 			 * If traced, always stop.
 			 */
 			mtx_unlock(&ps->ps_mtx);
-			ptracestop(td, sig);
-			PROC_LOCK(p);
+			newsig = ptracestop(td, sig);
 			mtx_lock(&ps->ps_mtx);
 
 			/*
@@ -2091,10 +2121,11 @@
 			 * otherwise we just look for signals again.
 			 */
 			SIGDELSET(td->td_siglist, sig);	/* clear old signal */
-			sig = p->p_xstat;
-			if (sig == 0)
+			if (td->td_pflags & TDP_SA)
+				SIGADDSET(td->td_sigmask, sig);
+			if (newsig == 0)
 				continue;
-
+			sig = newsig;
 			/*
 			 * If the traced bit got turned off, go back up
 			 * to the top to rescan signals.  This ensures
@@ -2108,6 +2139,8 @@
 			 * signal is being masked, look for other signals.
 			 */
 			SIGADDSET(td->td_siglist, sig);
+			if (td->td_pflags & TDP_SA)
+				SIGDELSET(td->td_sigmask, sig);
 			if (SIGISMEMBER(td->td_sigmask, sig))
 				continue;
 			signotify(td);
@@ -2286,8 +2319,7 @@
 		mtx_lock(&ps->ps_mtx);
 	}
 
-	if (!(td->td_pflags & TDP_SA && td->td_mailbox) &&
-	    action == SIG_DFL) {
+	if (!(td->td_pflags & TDP_SA) && action == SIG_DFL) {
 		/*
 		 * Default action, where the default is to kill
 		 * the process.  (Other cases were ignored above.)
@@ -2296,7 +2328,7 @@
 		sigexit(td, sig);
 		/* NOTREACHED */
 	} else {
-		if (td->td_pflags & TDP_SA && td->td_mailbox) {
+		if (td->td_pflags & TDP_SA) {
 			if (sig == SIGKILL) {
 				mtx_unlock(&ps->ps_mtx);
 				sigexit(td, sig);
@@ -2345,7 +2377,7 @@
 			p->p_code = 0;
 			p->p_sig = 0;
 		}
-		if (td->td_pflags & TDP_SA && td->td_mailbox)
+		if (td->td_pflags & TDP_SA)
 			thread_signal_add(curthread, sig);
 		else
 			(*p->p_sysent->sv_sendsig)(action, sig,


More information about the p4-projects mailing list