diff options
| author | 2012-04-13 16:37:50 +0000 | |
|---|---|---|
| committer | 2012-04-13 16:37:50 +0000 | |
| commit | 4ec195400d023537d947ee6557938900b7cc7161 (patch) | |
| tree | ae5a44c0389aa411ffbe8060c039ba000dad12a8 /sys/kern/kern_sig.c | |
| parent | Don't try to mmap a 0-length file. (diff) | |
| download | wireguard-openbsd-4ec195400d023537d947ee6557938900b7cc7161.tar.xz wireguard-openbsd-4ec195400d023537d947ee6557938900b7cc7161.zip | |
First stab at making ptrace(2) usable for debugging multi-threaded programs.
It implements a full-stop model where all threads are stopped before handing
over control to the debugger. Events are reported as before through wait(2);
you will have to call ptrace(PT_GET_PROCESS_STATE, ...) to find out which
thread hit the event. Since this changes the size of struct ptrace_state,
you will have to recompile gdb.
ok guenther@
Diffstat (limited to 'sys/kern/kern_sig.c')
| -rw-r--r-- | sys/kern/kern_sig.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 991744db1d3..c1cb5857ce0 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.140 2012/04/12 10:11:41 mikeb Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.141 2012/04/13 16:37:51 kettenis Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1072,12 +1072,20 @@ issignal(struct proc *p) */ p->p_xstat = signum; + KERNEL_LOCK(); + single_thread_set(p, SINGLE_SUSPEND, 0); + KERNEL_UNLOCK(); + if (dolock) SCHED_LOCK(s); proc_stop(p, 1); if (dolock) SCHED_UNLOCK(s); + KERNEL_LOCK(); + single_thread_clear(p, 0); + KERNEL_UNLOCK(); + /* * If we are no longer being traced, or the parent * didn't give us a signal, look for more signals. @@ -1766,7 +1774,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep) TAILQ_FOREACH(q, &pr->ps_threads, p_thr_link) { int s; - if (q == p) + if (q == p || ISSET(q->p_flag, P_WEXIT)) continue; SCHED_LOCK(s); atomic_setbits_int(&q->p_flag, P_SUSPSINGLE); @@ -1812,7 +1820,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep) } void -single_thread_clear(struct proc *p) +single_thread_clear(struct proc *p, int flag) { struct process *pr = p->p_p; struct proc *q; @@ -1834,7 +1842,7 @@ single_thread_clear(struct proc *p) * it back into some sleep queue */ SCHED_LOCK(s); - if (q->p_stat == SSTOP && (q->p_flag & P_SUSPSIG) == 0) { + if (q->p_stat == SSTOP && (q->p_flag & flag) == 0) { if (q->p_wchan == 0) setrunnable(q); else |
