Commit 67176db2 authored by Ingo Molnar's avatar Ingo Molnar

this is a fragile piece of the ptrace code, the code relies on a single wakeup...

this is a fragile piece of the ptrace code, the code relies on a single wakeup coming from the parent.
This fix is necessery after the preempt_schedule() cleanups, it unbreaks 'strace strace ...'.
parent 4597f0c0
...@@ -455,9 +455,11 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) ...@@ -455,9 +455,11 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
between a syscall stop and SIGTRAP delivery */ between a syscall stop and SIGTRAP delivery */
current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0); ? 0x80 : 0);
preempt_disable();
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
/* /*
* this isn't the same as continuing with a signal, but it will do * this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the * for normal use. strace only continues with a signal if the
......
...@@ -610,9 +610,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -610,9 +610,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */ /* Let the debugger run. */
current->exit_code = signr; current->exit_code = signr;
preempt_disable();
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
/* We're back. Did the debugger cancel the sig? */ /* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
...@@ -667,12 +669,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -667,12 +669,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->p_pptr->sig; sig = current->p_pptr->sig;
preempt_disable();
current->state = TASK_STOPPED;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment