aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2007-07-16 02:40:10 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:43 -0400
commit45807a1df9f51d28d0ff0c6bcf900c210411d7c9 (patch)
treedf70e9162ce50ada2393987ca2a5b5794dcbb644
parent99fc06df72fe1c9ad3ec274720dcb5658c40bfd2 (diff)
vdso: print fatal signals
Add the print-fatal-signals=1 boot option and the /proc/sys/kernel/print-fatal-signals runtime switch. This feature prints some minimal information about userspace segfaults to the kernel console. This is useful to find early bootup bugs where userspace debugging is very hard. Defaults to off. [akpm@linux-foundation.org: Don't add new sysctl numbers] Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Arjan van de Ven <arjan@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--kernel/signal.c33
-rw-r--r--kernel/sysctl.c9
3 files changed, 48 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 182c6a39d5a2..ab38322111c4 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1383,6 +1383,12 @@ and is between 256 and 4096 characters. It is defined in the file
1383 autoconfiguration. 1383 autoconfiguration.
1384 Ranges are in pairs (memory base and size). 1384 Ranges are in pairs (memory base and size).
1385 1385
1386 print-fatal-signals=
1387 [KNL] debug: print fatal signals
1388 print-fatal-signals=1: print segfault info to
1389 the kernel console.
1390 default: off.
1391
1386 profile= [KNL] Enable kernel profiling via /proc/profile 1392 profile= [KNL] Enable kernel profiling via /proc/profile
1387 Format: [schedule,]<number> 1393 Format: [schedule,]<number>
1388 Param: "schedule" - profile schedule points. 1394 Param: "schedule" - profile schedule points.
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
721int print_fatal_signals;
722
723static 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
744static 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
722static int 753static int
723specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) 754specific_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. */
63extern int C_A_D; 63extern int C_A_D;
64extern int print_fatal_signals;
64extern int sysctl_overcommit_memory; 65extern int sysctl_overcommit_memory;
65extern int sysctl_overcommit_ratio; 66extern int sysctl_overcommit_ratio;
66extern int sysctl_panic_on_oom; 67extern 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,