diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-07-02 09:19:22 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-07-02 09:19:22 +0000 |
commit | e7a5dd69acca58e5338b737cf0b4a77c603e40b8 (patch) | |
tree | bb7d239a9ec478d673b87467492d1980639d474f /sys | |
parent | a6d7df1ec2b6fb69b4b196a4cc0cdadc327463de (diff) | |
download | FreeBSD-src-e7a5dd69acca58e5338b737cf0b4a77c603e40b8.zip FreeBSD-src-e7a5dd69acca58e5338b737cf0b4a77c603e40b8.tar.gz |
Allow ptrace to deal with lwpid.
Reviewed by: marcel
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/sys_process.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index a43e7b0..f65b67c 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -365,10 +365,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) struct iovec iov; struct uio uio; struct proc *curp, *p, *pp; - struct thread *td2; + struct thread *td2 = NULL; struct ptrace_io_desc *piod; int error, write, tmp; int proctree_locked = 0; + lwpid_t tid = 0; curp = td->td_proc; @@ -393,10 +394,35 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) p = td->td_proc; PROC_LOCK(p); } else { - if ((p = pfind(pid)) == NULL) { - if (proctree_locked) - sx_xunlock(&proctree_lock); - return (ESRCH); + if (pid <= PID_MAX) { + if ((p = pfind(pid)) == NULL) { + if (proctree_locked) + sx_xunlock(&proctree_lock); + return (ESRCH); + } + } else { + /* this is slow, should be optimized */ + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + PROC_LOCK(p); + mtx_lock_spin(&sched_lock); + FOREACH_THREAD_IN_PROC(p, td2) { + if (td2->td_tid == pid) + break; + } + mtx_unlock_spin(&sched_lock); + if (td2 != NULL) + break; /* proc lock held */ + PROC_UNLOCK(p); + } + sx_sunlock(&allproc_lock); + if (p == NULL) { + if (proctree_locked) + sx_xunlock(&proctree_lock); + return (ESRCH); + } + tid = pid; + pid = p->p_pid; } } if ((error = p_cansee(td, p)) != 0) @@ -413,6 +439,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) goto fail; } + if (tid == 0) { + td2 = FIRST_THREAD_IN_PROC(p); + tid = td2->td_tid; + } + /* * Permissions check */ @@ -471,7 +502,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) break; } - td2 = FIRST_THREAD_IN_PROC(p); #ifdef FIX_SSTEP /* * Single step fixup ala procfs |