diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-10-15 06:31:37 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-10-15 06:31:37 +0000 |
commit | 5068f6dcf0f3c2ae8be0b0774cd1d74f11085fbd (patch) | |
tree | b5ea5e6ee198214fb2b60f739b585b03f37900b2 | |
parent | e5b69cb78e39e1043228664f5667e46f361af000 (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/kern/kern_exit.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 4 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 17 | ||||
-rw-r--r-- | sys/sys/proc.h | 9 |
5 files changed, 22 insertions, 24 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; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 66e95ac..b326ba7 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -232,6 +232,7 @@ struct thread { u_int td_profil_ticks; /* (k) Temporary ticks until AST. */ char td_name[MAXCOMLEN + 1]; /* (*) Thread name. */ struct file *td_fpop; /* (k) file referencing cdev under op */ + int td_dbgflags; /* (c) Userland debugger flags */ #define td_endzero td_base_pri /* Copied during fork1() or thread_sched_upcall(). */ @@ -318,10 +319,10 @@ do { \ #define TDF_NEEDSUSPCHK 0x00008000 /* Thread may need to suspend. */ #define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */ #define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */ -#define TDF_XSIG 0x00040000 /* Thread is exchanging signal under trace */ +#define TDF_UNUSED18 0x00040000 /* --available-- */ #define TDF_UNUSED19 0x00080000 /* Thread is sleeping on a umtx. */ #define TDF_THRWAKEUP 0x00100000 /* Libthr thread must not suspend itself. */ -#define TDF_DBSUSPEND 0x00200000 /* Thread is suspended by debugger */ +#define TDF_UNUSED21 0x00200000 /* --available-- */ #define TDF_SWAPINREQ 0x00400000 /* Swapin request due to wakeup. */ #define TDF_UNUSED23 0x00800000 /* --available-- */ #define TDF_SCHED0 0x01000000 /* Reserved for scheduler private use */ @@ -332,6 +333,10 @@ do { \ #define TDF_PROFPEND 0x20000000 /* Pending SIGPROF needs to be posted. */ #define TDF_MACPEND 0x40000000 /* AST-based MAC event pending. */ +/* Userland debug flags */ +#define TDB_SUSPEND 0x00000001 /* Thread is suspended by debugger */ +#define TDB_XSIG 0x00000002 /* Thread is exchanging signal under trace */ + /* * "Private" flags kept in td_pflags: * These are only written by curthread and thus need no locking. |