diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 1a942ce32ba0..10b31ecdd9c8 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1754,17 +1754,33 @@ relock: | |||
1754 | do_signal_stop(0)) | 1754 | do_signal_stop(0)) |
1755 | goto relock; | 1755 | goto relock; |
1756 | 1756 | ||
1757 | signr = dequeue_signal(current, ¤t->blocked, info); | 1757 | /* |
1758 | if (!signr) | 1758 | * Tracing can induce an artifical signal and choose sigaction. |
1759 | break; /* will return 0 */ | 1759 | * The return value in @signr determines the default action, |
1760 | * but @info->si_signo is the signal number we will report. | ||
1761 | */ | ||
1762 | signr = tracehook_get_signal(current, regs, info, return_ka); | ||
1763 | if (unlikely(signr < 0)) | ||
1764 | goto relock; | ||
1765 | if (unlikely(signr != 0)) | ||
1766 | ka = return_ka; | ||
1767 | else { | ||
1768 | signr = dequeue_signal(current, ¤t->blocked, | ||
1769 | info); | ||
1760 | 1770 | ||
1761 | if (signr != SIGKILL) { | ||
1762 | signr = ptrace_signal(signr, info, regs, cookie); | ||
1763 | if (!signr) | 1771 | if (!signr) |
1764 | continue; | 1772 | break; /* will return 0 */ |
1773 | |||
1774 | if (signr != SIGKILL) { | ||
1775 | signr = ptrace_signal(signr, info, | ||
1776 | regs, cookie); | ||
1777 | if (!signr) | ||
1778 | continue; | ||
1779 | } | ||
1780 | |||
1781 | ka = &sighand->action[signr-1]; | ||
1765 | } | 1782 | } |
1766 | 1783 | ||
1767 | ka = &sighand->action[signr-1]; | ||
1768 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ | 1784 | if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ |
1769 | continue; | 1785 | continue; |
1770 | if (ka->sa.sa_handler != SIG_DFL) { | 1786 | if (ka->sa.sa_handler != SIG_DFL) { |
@@ -1812,7 +1828,7 @@ relock: | |||
1812 | spin_lock_irq(&sighand->siglock); | 1828 | spin_lock_irq(&sighand->siglock); |
1813 | } | 1829 | } |
1814 | 1830 | ||
1815 | if (likely(do_signal_stop(signr))) { | 1831 | if (likely(do_signal_stop(info->si_signo))) { |
1816 | /* It released the siglock. */ | 1832 | /* It released the siglock. */ |
1817 | goto relock; | 1833 | goto relock; |
1818 | } | 1834 | } |
@@ -1833,7 +1849,7 @@ relock: | |||
1833 | 1849 | ||
1834 | if (sig_kernel_coredump(signr)) { | 1850 | if (sig_kernel_coredump(signr)) { |
1835 | if (print_fatal_signals) | 1851 | if (print_fatal_signals) |
1836 | print_fatal_signal(regs, signr); | 1852 | print_fatal_signal(regs, info->si_signo); |
1837 | /* | 1853 | /* |
1838 | * If it was able to dump core, this kills all | 1854 | * If it was able to dump core, this kills all |
1839 | * other threads in the group and synchronizes with | 1855 | * other threads in the group and synchronizes with |
@@ -1842,13 +1858,13 @@ relock: | |||
1842 | * first and our do_group_exit call below will use | 1858 | * first and our do_group_exit call below will use |
1843 | * that value and ignore the one we pass it. | 1859 | * that value and ignore the one we pass it. |
1844 | */ | 1860 | */ |
1845 | do_coredump((long)signr, signr, regs); | 1861 | do_coredump(info->si_signo, info->si_signo, regs); |
1846 | } | 1862 | } |
1847 | 1863 | ||
1848 | /* | 1864 | /* |
1849 | * Death signals, no core dump. | 1865 | * Death signals, no core dump. |
1850 | */ | 1866 | */ |
1851 | do_group_exit(signr); | 1867 | do_group_exit(info->si_signo); |
1852 | /* NOTREACHED */ | 1868 | /* NOTREACHED */ |
1853 | } | 1869 | } |
1854 | spin_unlock_irq(&sighand->siglock); | 1870 | spin_unlock_irq(&sighand->siglock); |