summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2008-10-15 06:31:37 +0000
committerdavidxu <davidxu@FreeBSD.org>2008-10-15 06:31:37 +0000
commit5068f6dcf0f3c2ae8be0b0774cd1d74f11085fbd (patch)
treeb5ea5e6ee198214fb2b60f739b585b03f37900b2 /sys/kern
parente5b69cb78e39e1043228664f5667e46f361af000 (diff)
downloadFreeBSD-src-5068f6dcf0f3c2ae8be0b0774cd1d74f11085fbd.zip
FreeBSD-src-5068f6dcf0f3c2ae8be0b0774cd1d74f11085fbd.tar.gz
Move per-thread userland debugging flags into seperated field,
this eliminates some problems of locking, e.g, a thread lock is needed but can not be used at that time. Only the process lock is needed now for new field.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exit.c4
-rw-r--r--sys/kern/kern_sig.c12
-rw-r--r--sys/kern/kern_thread.c4
-rw-r--r--sys/kern/sys_process.c17
4 files changed, 15 insertions, 22 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index e956cdf..6ebe032 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -438,7 +438,11 @@ exit1(struct thread *td, int rv)
* since their existence means someone is screwing up.
*/
if (q->p_flag & P_TRACED) {
+ struct thread *temp;
+
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
+ FOREACH_THREAD_IN_PROC(q, temp)
+ temp->td_dbgflags &= ~TDB_SUSPEND;
psignal(q, SIGKILL);
}
PROC_UNLOCK(q);
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index d5d1813..f4cf8ad 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2342,16 +2342,12 @@ ptracestop(struct thread *td, int sig)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
&p->p_mtx.lock_object, "Stopping for traced signal");
- thread_lock(td);
- td->td_flags |= TDF_XSIG;
- thread_unlock(td);
+ td->td_dbgflags |= TDB_XSIG;
td->td_xsig = sig;
PROC_SLOCK(p);
- while ((p->p_flag & P_TRACED) && (td->td_flags & TDF_XSIG)) {
+ while ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_XSIG)) {
if (p->p_flag & P_SINGLE_EXIT) {
- thread_lock(td);
- td->td_flags &= ~TDF_XSIG;
- thread_unlock(td);
+ td->td_dbgflags &= ~TDB_XSIG;
PROC_SUNLOCK(p);
return (sig);
}
@@ -2368,7 +2364,7 @@ stopme:
if (!(p->p_flag & P_TRACED)) {
break;
}
- if (td->td_flags & TDF_DBSUSPEND) {
+ if (td->td_dbgflags & TDB_SUSPEND) {
if (p->p_flag & P_SINGLE_EXIT)
break;
goto stopme;
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index bb87696..7298edc 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -563,8 +563,6 @@ thread_single(int mode)
if (TD_IS_INHIBITED(td2)) {
switch (mode) {
case SINGLE_EXIT:
- if (td->td_flags & TDF_DBSUSPEND)
- td->td_flags &= ~TDF_DBSUSPEND;
if (TD_IS_SUSPENDED(td2))
wakeup_swapper |=
thread_unsuspend_one(td2);
@@ -685,7 +683,7 @@ thread_suspend_check(int return_instead)
mtx_assert(&Giant, MA_NOTOWNED);
PROC_LOCK_ASSERT(p, MA_OWNED);
while (P_SHOULDSTOP(p) ||
- ((p->p_flag & P_TRACED) && (td->td_flags & TDF_DBSUSPEND))) {
+ ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_SUSPEND))) {
if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) {
KASSERT(p->p_singlethread != NULL,
("singlethread not set"));
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index dbdd30f..ceae8de 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -700,15 +700,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_SUSPEND:
+ td2->td_dbgflags |= TDB_SUSPEND;
thread_lock(td2);
- td2->td_flags |= TDF_DBSUSPEND;
+ td2->td_flags |= TDF_NEEDSUSPCHK;
thread_unlock(td2);
break;
case PT_RESUME:
- thread_lock(td2);
- td2->td_flags &= ~TDF_DBSUSPEND;
- thread_unlock(td2);
+ td2->td_dbgflags &= ~TDB_SUSPEND;
break;
case PT_STEP:
@@ -782,17 +781,13 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
p->p_xthread = NULL;
if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) != 0) {
/* deliver or queue signal */
- thread_lock(td2);
- td2->td_flags &= ~TDF_XSIG;
- thread_unlock(td2);
+ td2->td_dbgflags &= ~TDB_XSIG;
td2->td_xsig = data;
if (req == PT_DETACH) {
struct thread *td3;
FOREACH_THREAD_IN_PROC(p, td3) {
- thread_lock(td3);
- td3->td_flags &= ~TDF_DBSUSPEND;
- thread_unlock(td3);
+ td3->td_dbgflags &= ~TDB_SUSPEND;
}
}
/*
@@ -932,7 +927,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
}
pl = addr;
pl->pl_lwpid = td2->td_tid;
- if (td2->td_flags & TDF_XSIG)
+ if (td2->td_dbgflags & TDB_XSIG)
pl->pl_event = PL_EVENT_SIGNAL;
else
pl->pl_event = 0;
OpenPOWER on IntegriCloud