Skip to content

Commit 45807a1

Browse files
Ingo MolnarLinus Torvalds
authored andcommitted
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>
1 parent 99fc06d commit 45807a1

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

Documentation/kernel-parameters.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,12 @@ and is between 256 and 4096 characters. It is defined in the file
13831383
autoconfiguration.
13841384
Ranges are in pairs (memory base and size).
13851385

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+
13861392
profile= [KNL] Enable kernel profiling via /proc/profile
13871393
Format: [schedule,]<number>
13881394
Param: "schedule" - profile schedule points.

kernel/signal.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,37 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
718718
#define LEGACY_QUEUE(sigptr, sig) \
719719
(((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
720720

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);
721752

722753
static int
723754
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,
18551886
* Anything else is fatal, maybe with a core dump.
18561887
*/
18571888
current->flags |= PF_SIGNALED;
1889+
if ((signr != SIGKILL) && print_fatal_signals)
1890+
print_fatal_signal(regs, signr);
18581891
if (sig_kernel_coredump(signr)) {
18591892
/*
18601893
* If it was able to dump core, this kills all

kernel/sysctl.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp,
6161

6262
/* External variables not in a header file. */
6363
extern int C_A_D;
64+
extern int print_fatal_signals;
6465
extern int sysctl_overcommit_memory;
6566
extern int sysctl_overcommit_ratio;
6667
extern int sysctl_panic_on_oom;
@@ -340,6 +341,14 @@ static ctl_table kern_table[] = {
340341
.proc_handler = &proc_dointvec,
341342
},
342343
#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+
},
343352
#ifdef __sparc__
344353
{
345354
.ctl_name = KERN_SPARC_REBOOT,

0 commit comments

Comments
 (0)