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.
This commit is contained in:
parent
e5b69cb78e
commit
5068f6dcf0
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user