diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 33 | ||||
-rw-r--r-- | kernel/sysctl.c | 9 |
2 files changed, 42 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index f9405609774e..39d122753bac 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -718,6 +718,37 @@ out_set: | |||
718 | #define LEGACY_QUEUE(sigptr, sig) \ | 718 | #define LEGACY_QUEUE(sigptr, sig) \ |
719 | (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig))) | 719 | (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig))) |
720 | 720 | ||
721 | int print_fatal_signals; | ||
722 | |||
723 | static void print_fatal_signal(struct pt_regs *regs, int signr) | ||
724 | { | ||
725 | printk("%s/%d: potentially unexpected fatal signal %d.\n", | ||
726 | current->comm, current->pid, signr); | ||
727 | |||
728 | #ifdef __i386__ | ||
729 | printk("code at %08lx: ", regs->eip); | ||
730 | { | ||
731 | int i; | ||
732 | for (i = 0; i < 16; i++) { | ||
733 | unsigned char insn; | ||
734 | |||
735 | __get_user(insn, (unsigned char *)(regs->eip + i)); | ||
736 | printk("%02x ", insn); | ||
737 | } | ||
738 | } | ||
739 | #endif | ||
740 | printk("\n"); | ||
741 | show_regs(regs); | ||
742 | } | ||
743 | |||
744 | static int __init setup_print_fatal_signals(char *str) | ||
745 | { | ||
746 | get_option (&str, &print_fatal_signals); | ||
747 | |||
748 | return 1; | ||
749 | } | ||
750 | |||
751 | __setup("print-fatal-signals=", setup_print_fatal_signals); | ||
721 | 752 | ||
722 | static int | 753 | static int |
723 | specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) | 754 | specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) |
@@ -1855,6 +1886,8 @@ relock: | |||
1855 | * Anything else is fatal, maybe with a core dump. | 1886 | * Anything else is fatal, maybe with a core dump. |
1856 | */ | 1887 | */ |
1857 | current->flags |= PF_SIGNALED; | 1888 | current->flags |= PF_SIGNALED; |
1889 | if ((signr != SIGKILL) && print_fatal_signals) | ||
1890 | print_fatal_signal(regs, signr); | ||
1858 | if (sig_kernel_coredump(signr)) { | 1891 | if (sig_kernel_coredump(signr)) { |
1859 | /* | 1892 | /* |
1860 | * If it was able to dump core, this kills all | 1893 | * If it was able to dump core, this kills all |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ccaebbbd75ae..2cce2286bdcd 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -61,6 +61,7 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp, | |||
61 | 61 | ||
62 | /* External variables not in a header file. */ | 62 | /* External variables not in a header file. */ |
63 | extern int C_A_D; | 63 | extern int C_A_D; |
64 | extern int print_fatal_signals; | ||
64 | extern int sysctl_overcommit_memory; | 65 | extern int sysctl_overcommit_memory; |
65 | extern int sysctl_overcommit_ratio; | 66 | extern int sysctl_overcommit_ratio; |
66 | extern int sysctl_panic_on_oom; | 67 | extern int sysctl_panic_on_oom; |
@@ -340,6 +341,14 @@ static ctl_table kern_table[] = { | |||
340 | .proc_handler = &proc_dointvec, | 341 | .proc_handler = &proc_dointvec, |
341 | }, | 342 | }, |
342 | #endif | 343 | #endif |
344 | { | ||
345 | .ctl_name = CTL_UNNUMBERED, | ||
346 | .procname = "print-fatal-signals", | ||
347 | .data = &print_fatal_signals, | ||
348 | .maxlen = sizeof(int), | ||
349 | .mode = 0644, | ||
350 | .proc_handler = &proc_dointvec, | ||
351 | }, | ||
343 | #ifdef __sparc__ | 352 | #ifdef __sparc__ |
344 | { | 353 | { |
345 | .ctl_name = KERN_SPARC_REBOOT, | 354 | .ctl_name = KERN_SPARC_REBOOT, |