Skip to content

Commit

Permalink
ptrace_signal subroutine
Browse files Browse the repository at this point in the history
This breaks out the ptrace handling from get_signal_to_deliver into a
new subroutine.  The actual code there doesn't change, and it gets
inlined into nearly identical compiled code.  This makes the function
substantially shorter and thus easier to read, and it nicely isolates
the ptrace magic.

Signed-off-by: Roland McGrath <roland@redhat.com>
Acked-by: Kyle McMartin <kyle@mcmartin.ca>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Roland McGrath authored and Linus Torvalds committed Apr 18, 2008
1 parent 0e04388 commit 18c98b6
Showing 1 changed file with 42 additions and 29 deletions.
71 changes: 42 additions & 29 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,45 @@ static int do_signal_stop(int signr)
return 1;
}

static int ptrace_signal(int signr, siginfo_t *info,
struct pt_regs *regs, void *cookie)
{
if (!(current->ptrace & PT_PTRACED))
return signr;

ptrace_signal_deliver(regs, cookie);

/* Let the debugger run. */
ptrace_stop(signr, 0, info);

/* We're back. Did the debugger cancel the sig? */
signr = current->exit_code;
if (signr == 0)
return signr;

current->exit_code = 0;

/* Update the siginfo structure if the signal has
changed. If the debugger wanted something
specific in the siginfo structure then it should
have updated *info via PTRACE_SETSIGINFO. */
if (signr != info->si_signo) {
info->si_signo = signr;
info->si_errno = 0;
info->si_code = SI_USER;
info->si_pid = task_pid_vnr(current->parent);
info->si_uid = current->parent->uid;
}

/* If the (new) signal is now blocked, requeue it. */
if (sigismember(&current->blocked, signr)) {
specific_send_sig_info(signr, info, current);
signr = 0;
}

return signr;
}

int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
struct pt_regs *regs, void *cookie)
{
Expand Down Expand Up @@ -1785,36 +1824,10 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
if (!signr)
break; /* will return 0 */

if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
ptrace_signal_deliver(regs, cookie);

/* Let the debugger run. */
ptrace_stop(signr, 0, info);

/* We're back. Did the debugger cancel the sig? */
signr = current->exit_code;
if (signr == 0)
continue;

current->exit_code = 0;

/* Update the siginfo structure if the signal has
changed. If the debugger wanted something
specific in the siginfo structure then it should
have updated *info via PTRACE_SETSIGINFO. */
if (signr != info->si_signo) {
info->si_signo = signr;
info->si_errno = 0;
info->si_code = SI_USER;
info->si_pid = task_pid_vnr(current->parent);
info->si_uid = current->parent->uid;
}

/* If the (new) signal is now blocked, requeue it. */
if (sigismember(&current->blocked, signr)) {
specific_send_sig_info(signr, info, current);
if (signr != SIGKILL) {
signr = ptrace_signal(signr, info, regs, cookie);
if (!signr)
continue;
}
}

ka = &current->sighand->action[signr-1];
Expand Down

0 comments on commit 18c98b6

Please sign in to comment.