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