Commit 45807a1d authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

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: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarArjan van de Ven <arjan@infradead.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 99fc06df
...@@ -1383,6 +1383,12 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1383,6 +1383,12 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration. autoconfiguration.
Ranges are in pairs (memory base and size). Ranges are in pairs (memory base and size).
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to
the kernel console.
default: off.
profile= [KNL] Enable kernel profiling via /proc/profile profile= [KNL] Enable kernel profiling via /proc/profile
Format: [schedule,]<number> Format: [schedule,]<number>
Param: "schedule" - profile schedule points. Param: "schedule" - profile schedule points.
......
...@@ -718,6 +718,37 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, ...@@ -718,6 +718,37 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
#define LEGACY_QUEUE(sigptr, sig) \ #define LEGACY_QUEUE(sigptr, sig) \
(((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig))) (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
int print_fatal_signals;
static void print_fatal_signal(struct pt_regs *regs, int signr)
{
printk("%s/%d: potentially unexpected fatal signal %d.\n",
current->comm, current->pid, signr);
#ifdef __i386__
printk("code at %08lx: ", regs->eip);
{
int i;
for (i = 0; i < 16; i++) {
unsigned char insn;
__get_user(insn, (unsigned char *)(regs->eip + i));
printk("%02x ", insn);
}
}
#endif
printk("\n");
show_regs(regs);
}
static int __init setup_print_fatal_signals(char *str)
{
get_option (&str, &print_fatal_signals);
return 1;
}
__setup("print-fatal-signals=", setup_print_fatal_signals);
static int static int
specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
...@@ -1855,6 +1886,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, ...@@ -1855,6 +1886,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
* Anything else is fatal, maybe with a core dump. * Anything else is fatal, maybe with a core dump.
*/ */
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
if ((signr != SIGKILL) && print_fatal_signals)
print_fatal_signal(regs, signr);
if (sig_kernel_coredump(signr)) { if (sig_kernel_coredump(signr)) {
/* /*
* If it was able to dump core, this kills all * If it was able to dump core, this kills all
......
...@@ -61,6 +61,7 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp, ...@@ -61,6 +61,7 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp,
/* External variables not in a header file. */ /* External variables not in a header file. */
extern int C_A_D; extern int C_A_D;
extern int print_fatal_signals;
extern int sysctl_overcommit_memory; extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio; extern int sysctl_overcommit_ratio;
extern int sysctl_panic_on_oom; extern int sysctl_panic_on_oom;
...@@ -340,6 +341,14 @@ static ctl_table kern_table[] = { ...@@ -340,6 +341,14 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
}, },
#endif #endif
{
.ctl_name = CTL_UNNUMBERED,
.procname = "print-fatal-signals",
.data = &print_fatal_signals,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
#ifdef __sparc__ #ifdef __sparc__
{ {
.ctl_name = KERN_SPARC_REBOOT, .ctl_name = KERN_SPARC_REBOOT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment