aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index b5f55ca1f43f..589292f38530 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1873,21 +1873,26 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1873 recalc_sigpending_tsk(current); 1873 recalc_sigpending_tsk(current);
1874} 1874}
1875 1875
1876void ptrace_notify(int exit_code) 1876static void ptrace_do_notify(int signr, int exit_code, int why)
1877{ 1877{
1878 siginfo_t info; 1878 siginfo_t info;
1879 1879
1880 BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);
1881
1882 memset(&info, 0, sizeof info); 1880 memset(&info, 0, sizeof info);
1883 info.si_signo = SIGTRAP; 1881 info.si_signo = signr;
1884 info.si_code = exit_code; 1882 info.si_code = exit_code;
1885 info.si_pid = task_pid_vnr(current); 1883 info.si_pid = task_pid_vnr(current);
1886 info.si_uid = current_uid(); 1884 info.si_uid = current_uid();
1887 1885
1888 /* Let the debugger run. */ 1886 /* Let the debugger run. */
1887 ptrace_stop(exit_code, why, 1, &info);
1888}
1889
1890void ptrace_notify(int exit_code)
1891{
1892 BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);
1893
1889 spin_lock_irq(&current->sighand->siglock); 1894 spin_lock_irq(&current->sighand->siglock);
1890 ptrace_stop(exit_code, CLD_TRAPPED, 1, &info); 1895 ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED);
1891 spin_unlock_irq(&current->sighand->siglock); 1896 spin_unlock_irq(&current->sighand->siglock);
1892} 1897}
1893 1898
@@ -2017,7 +2022,13 @@ static bool do_signal_stop(int signr)
2017/** 2022/**
2018 * do_jobctl_trap - take care of ptrace jobctl traps 2023 * do_jobctl_trap - take care of ptrace jobctl traps
2019 * 2024 *
2020 * It is currently used only to trap for group stop while ptraced. 2025 * When PT_SEIZED, it's used for both group stop and explicit
2026 * SEIZE/INTERRUPT traps. Both generate PTRACE_EVENT_STOP trap with
2027 * accompanying siginfo. If stopped, lower eight bits of exit_code contain
2028 * the stop signal; otherwise, %SIGTRAP.
2029 *
2030 * When !PT_SEIZED, it's used only for group stop trap with stop signal
2031 * number as exit_code and no siginfo.
2021 * 2032 *
2022 * CONTEXT: 2033 * CONTEXT:
2023 * Must be called with @current->sighand->siglock held, which may be 2034 * Must be called with @current->sighand->siglock held, which may be
@@ -2025,11 +2036,21 @@ static bool do_signal_stop(int signr)
2025 */ 2036 */
2026static void do_jobctl_trap(void) 2037static void do_jobctl_trap(void)
2027{ 2038{
2039 struct signal_struct *signal = current->signal;
2028 int signr = current->jobctl & JOBCTL_STOP_SIGMASK; 2040 int signr = current->jobctl & JOBCTL_STOP_SIGMASK;
2029 2041
2030 WARN_ON_ONCE(!signr); 2042 if (current->ptrace & PT_SEIZED) {
2031 ptrace_stop(signr, CLD_STOPPED, 0, NULL); 2043 if (!signal->group_stop_count &&
2032 current->exit_code = 0; 2044 !(signal->flags & SIGNAL_STOP_STOPPED))
2045 signr = SIGTRAP;
2046 WARN_ON_ONCE(!signr);
2047 ptrace_do_notify(signr, signr | (PTRACE_EVENT_STOP << 8),
2048 CLD_STOPPED);
2049 } else {
2050 WARN_ON_ONCE(!signr);
2051 ptrace_stop(signr, CLD_STOPPED, 0, NULL);
2052 current->exit_code = 0;
2053 }
2033} 2054}
2034 2055
2035static int ptrace_signal(int signr, siginfo_t *info, 2056static int ptrace_signal(int signr, siginfo_t *info,