Commit 18c98b65 authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds
Browse files

ptrace_signal subroutine



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: default avatarRoland McGrath <roland@redhat.com>
Acked-by: default avatarKyle McMartin <kyle@mcmartin.ca>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 0e04388f
Loading
Loading
Loading
Loading
+42 −29
Original line number Diff line number Diff line
@@ -1757,35 +1757,12 @@ static int do_signal_stop(int signr)
	return 1;
}

int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
static int ptrace_signal(int signr, siginfo_t *info,
			 struct pt_regs *regs, void *cookie)
{
	sigset_t *mask = &current->blocked;
	int signr = 0;

relock:
	/*
	 * We'll jump back here after any time we were stopped in TASK_STOPPED.
	 * While in TASK_STOPPED, we were considered "frozen enough".
	 * Now that we woke up, it's crucial if we're supposed to be
	 * frozen that we freeze now before running anything substantial.
	 */
	try_to_freeze();

	spin_lock_irq(&current->sighand->siglock);
	for (;;) {
		struct k_sigaction *ka;

		if (unlikely(current->signal->group_stop_count > 0) &&
		    do_signal_stop(0))
			goto relock;

		signr = dequeue_signal(current, mask, info);

		if (!signr)
			break; /* will return 0 */
	if (!(current->ptrace & PT_PTRACED))
		return signr;

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

	/* Let the debugger run.  */
@@ -1794,7 +1771,7 @@ relock:
	/* We're back.  Did the debugger cancel the sig?  */
	signr = current->exit_code;
	if (signr == 0)
				continue;
		return signr;

	current->exit_code = 0;

@@ -1813,8 +1790,44 @@ relock:
	/* If the (new) signal is now blocked, requeue it.  */
	if (sigismember(&current->blocked, signr)) {
		specific_send_sig_info(signr, info, current);
				continue;
		signr = 0;
	}

	return signr;
}

int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
			  struct pt_regs *regs, void *cookie)
{
	sigset_t *mask = &current->blocked;
	int signr = 0;

relock:
	/*
	 * We'll jump back here after any time we were stopped in TASK_STOPPED.
	 * While in TASK_STOPPED, we were considered "frozen enough".
	 * Now that we woke up, it's crucial if we're supposed to be
	 * frozen that we freeze now before running anything substantial.
	 */
	try_to_freeze();

	spin_lock_irq(&current->sighand->siglock);
	for (;;) {
		struct k_sigaction *ka;

		if (unlikely(current->signal->group_stop_count > 0) &&
		    do_signal_stop(0))
			goto relock;

		signr = dequeue_signal(current, mask, info);

		if (!signr)
			break; /* will return 0 */

		if (signr != SIGKILL) {
			signr = ptrace_signal(signr, info, regs, cookie);
			if (!signr)
				continue;
		}

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