aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c79
1 files changed, 66 insertions, 13 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 418776c41d24..1e199919ae09 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -224,6 +224,26 @@ static inline void print_dropped_signal(int sig)
224} 224}
225 225
226/** 226/**
227 * task_clear_group_stop_trapping - clear group stop trapping bit
228 * @task: target task
229 *
230 * If GROUP_STOP_TRAPPING is set, a ptracer is waiting for us. Clear it
231 * and wake up the ptracer. Note that we don't need any further locking.
232 * @task->siglock guarantees that @task->parent points to the ptracer.
233 *
234 * CONTEXT:
235 * Must be called with @task->sighand->siglock held.
236 */
237static void task_clear_group_stop_trapping(struct task_struct *task)
238{
239 if (unlikely(task->group_stop & GROUP_STOP_TRAPPING)) {
240 task->group_stop &= ~GROUP_STOP_TRAPPING;
241 __wake_up_sync(&task->parent->signal->wait_chldexit,
242 TASK_UNINTERRUPTIBLE, 1);
243 }
244}
245
246/**
227 * task_clear_group_stop_pending - clear pending group stop 247 * task_clear_group_stop_pending - clear pending group stop
228 * @task: target task 248 * @task: target task
229 * 249 *
@@ -1706,8 +1726,20 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1706 current->last_siginfo = info; 1726 current->last_siginfo = info;
1707 current->exit_code = exit_code; 1727 current->exit_code = exit_code;
1708 1728
1709 /* Let the debugger run. */ 1729 /*
1710 __set_current_state(TASK_TRACED); 1730 * TRACED should be visible before TRAPPING is cleared; otherwise,
1731 * the tracer might fail do_wait().
1732 */
1733 set_current_state(TASK_TRACED);
1734
1735 /*
1736 * We're committing to trapping. Clearing GROUP_STOP_TRAPPING and
1737 * transition to TASK_TRACED should be atomic with respect to
1738 * siglock. This hsould be done after the arch hook as siglock is
1739 * released and regrabbed across it.
1740 */
1741 task_clear_group_stop_trapping(current);
1742
1711 spin_unlock_irq(&current->sighand->siglock); 1743 spin_unlock_irq(&current->sighand->siglock);
1712 read_lock(&tasklist_lock); 1744 read_lock(&tasklist_lock);
1713 if (may_ptrace_stop()) { 1745 if (may_ptrace_stop()) {
@@ -1788,6 +1820,9 @@ static int do_signal_stop(int signr)
1788 unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; 1820 unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME;
1789 struct task_struct *t; 1821 struct task_struct *t;
1790 1822
1823 /* signr will be recorded in task->group_stop for retries */
1824 WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK);
1825
1791 if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || 1826 if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) ||
1792 unlikely(signal_group_exit(sig))) 1827 unlikely(signal_group_exit(sig)))
1793 return 0; 1828 return 0;
@@ -1797,25 +1832,27 @@ static int do_signal_stop(int signr)
1797 */ 1832 */
1798 sig->group_exit_code = signr; 1833 sig->group_exit_code = signr;
1799 1834
1800 current->group_stop = gstop; 1835 current->group_stop &= ~GROUP_STOP_SIGMASK;
1836 current->group_stop |= signr | gstop;
1801 sig->group_stop_count = 1; 1837 sig->group_stop_count = 1;
1802 for (t = next_thread(current); t != current; t = next_thread(t)) 1838 for (t = next_thread(current); t != current;
1839 t = next_thread(t)) {
1840 t->group_stop &= ~GROUP_STOP_SIGMASK;
1803 /* 1841 /*
1804 * Setting state to TASK_STOPPED for a group 1842 * Setting state to TASK_STOPPED for a group
1805 * stop is always done with the siglock held, 1843 * stop is always done with the siglock held,
1806 * so this check has no races. 1844 * so this check has no races.
1807 */ 1845 */
1808 if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) { 1846 if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) {
1809 t->group_stop = gstop; 1847 t->group_stop |= signr | gstop;
1810 sig->group_stop_count++; 1848 sig->group_stop_count++;
1811 signal_wake_up(t, 0); 1849 signal_wake_up(t, 0);
1812 } else 1850 } else {
1813 task_clear_group_stop_pending(t); 1851 task_clear_group_stop_pending(t);
1852 }
1853 }
1814 } 1854 }
1815 1855retry:
1816 current->exit_code = sig->group_exit_code;
1817 __set_current_state(TASK_STOPPED);
1818
1819 if (likely(!task_ptrace(current))) { 1856 if (likely(!task_ptrace(current))) {
1820 int notify = 0; 1857 int notify = 0;
1821 1858
@@ -1827,6 +1864,7 @@ static int do_signal_stop(int signr)
1827 if (task_participate_group_stop(current)) 1864 if (task_participate_group_stop(current))
1828 notify = CLD_STOPPED; 1865 notify = CLD_STOPPED;
1829 1866
1867 __set_current_state(TASK_STOPPED);
1830 spin_unlock_irq(&current->sighand->siglock); 1868 spin_unlock_irq(&current->sighand->siglock);
1831 1869
1832 if (notify) { 1870 if (notify) {
@@ -1839,13 +1877,28 @@ static int do_signal_stop(int signr)
1839 schedule(); 1877 schedule();
1840 1878
1841 spin_lock_irq(&current->sighand->siglock); 1879 spin_lock_irq(&current->sighand->siglock);
1842 } else 1880 } else {
1843 ptrace_stop(current->exit_code, CLD_STOPPED, 0, NULL); 1881 ptrace_stop(current->group_stop & GROUP_STOP_SIGMASK,
1882 CLD_STOPPED, 0, NULL);
1883 current->exit_code = 0;
1884 }
1885
1886 /*
1887 * GROUP_STOP_PENDING could be set if another group stop has
1888 * started since being woken up or ptrace wants us to transit
1889 * between TASK_STOPPED and TRACED. Retry group stop.
1890 */
1891 if (current->group_stop & GROUP_STOP_PENDING) {
1892 WARN_ON_ONCE(!(current->group_stop & GROUP_STOP_SIGMASK));
1893 goto retry;
1894 }
1895
1896 /* PTRACE_ATTACH might have raced with task killing, clear trapping */
1897 task_clear_group_stop_trapping(current);
1844 1898
1845 spin_unlock_irq(&current->sighand->siglock); 1899 spin_unlock_irq(&current->sighand->siglock);
1846 1900
1847 tracehook_finish_jctl(); 1901 tracehook_finish_jctl();
1848 current->exit_code = 0;
1849 1902
1850 return 1; 1903 return 1;
1851} 1904}