Make i386 kernel show the segfaults in kernel dmesg, like x86_64.
PATCH 1/1 Make i386 kernel show the segfaults in kernel dmesg, like x86_64.
Hello,
This patch makes the i386 behave the same way that x86_64 does when a segfault happens. A line gets printed to the kernel log so that tools that need to check for failures can behave more uniformly between different kernels. Like x86_64, it can be disabled by setting debug.exception-trace sysctl variable to 0 (or by doing echo 0 > /proc/sys/debug/exception-trace)
Same behaviour can be extended to other architectures, if needed. cheers,
Masoud.
arch/i386/mm/fault.c +10 -1
@@ -283,6 +283,8 @@ static inline int vmalloc_fault(unsigned long address)return 0 ; } +int exception_trace =1 ; +/* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate
@@ -464,7 +466,14 @@ bad_area_nosemaphore:*/ if (is_prefetch (regs, address, error_code))return ; - +if (exception_trace &&unhandled_signal (tsk,SIGSEGV )) { +printk ( +"%s%s[%d]: segfault at %08lx eip %08lx esp %08lx error %lx\n" , + tsk->pid >1 ?KERN_INFO :KERN_EMERG , + tsk->comm, tsk->pid, address, regs->eip, + regs->esp, error_code); + } + tsk->thread.cr2 = address;/* Kernel addresses are always protection faults */ tsk->thread.error_code = error_code | (address >=TASK_SIZE );
arch/i386/mm/init.c +36 -0
@@ -854,3 +854,39 @@ void free_initrd_mem(unsigned long start, unsigned long end) }#endif +#ifdef CONFIG_SYSCTL +#include <linux/sysctl.h> + +extern int exception_trace; + +static ctl_table debug_table2[] = { + { + .ctl_name =99 , + .procname ="exception-trace" , + .data = &exception_trace, + .maxlen =sizeof (int ), + .mode =0644 , + .proc_handler = proc_dointvec + }, + {} +}; + +static ctl_table debug_root_table2[] = { + { + .ctl_name =CTL_DEBUG , + .procname ="debug" , + .mode =0555 , + .child = debug_table2 + }, + {} +}; + +static __init int i386_sysctl_init (void ) +{ +register_sysctl_table (debug_root_table2); +return 0 ; +} +__initcall (i386_sysctl_init); +#endif + +
arch/x86_64/mm/fault.c +0 -10
@@ -221,16 +221,6 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)return 0 ; } -int unhandled_signal (struct task_struct *tsk,int sig) -{ -if (is_init (tsk)) -return 1 ; -if (tsk->ptrace &PT_PTRACED ) -return 0 ; -return (tsk->sighand->action[sig-1 ].sa.sa_handler ==SIG_IGN ) || - (tsk->sighand->action[sig-1 ].sa.sa_handler ==SIG_DFL ); -} - static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,unsigned long error_code) {
include/asm-x86_64/proto.h +0 -2
@@ -75,8 +75,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long enextern void early_quirks (void );extern void check_efer (void ); -extern int unhandled_signal (struct task_struct *tsk,int sig); -extern void select_idle_routine (const struct cpuinfo_x86 *c);extern unsigned long table_start, table_end;
include/linux/signal.h +2 -0
@@ -244,6 +244,8 @@ extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,extern struct kmem_cache *sighand_cachep; +int unhandled_signal (struct task_struct *tsk,int sig); +/* * In POSIX a signal is sent either to a specific thread (Linux task) * or to the process as a whole (Linux thread group). How the signal
kernel/signal.c +10 -0
@@ -174,6 +174,16 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,return (q); } +int unhandled_signal (struct task_struct *tsk,int sig) +{ +if (is_init (tsk)) +return 1 ; +if (tsk->ptrace &PT_PTRACED ) +return 0 ; +return (tsk->sighand->action[sig-1 ].sa.sa_handler ==SIG_IGN ) || + (tsk->sighand->action[sig-1 ].sa.sa_handler ==SIG_DFL ); +} +static void __sigqueue_free (struct sigqueue *q) {if (q->flags &SIGQUEUE_PREALLOC )
Quoted 37 lines · On Tue, 5 Jun 2007 14:52:44 -0700 [email protected] (Masoud Asgharifard…
Hello,
This patch makes the i386 behave the same way thatx86_64does when a segfault happens. A line gets printed to the kernel log so that tools that need to check for failures can behave more uniformly between different kernels. Likex86_64, it can be disabled by setting debug.exception-trace sysctl variable to 0 (or by doing echo 0 >/proc/sys/debug/exception-trace)Same behaviour can be extended to other architectures, if needed. cheers,
Masoud.arch/i386/mm/init.c +24
-0+#ifdef CONFIG_SYSCTL +#include <linux/sysctl.h> + +extern int exception_trace; + +static ctl_table debug_table2[] = { + { + .ctl_name =99 , + .procname ="exception-trace" , + .data = &exception_trace, + .maxlen =sizeof (int ), + .mode =0644 , + .proc_handler = proc_dointvec + }, + {} +}; + +static ctl_table debug_root_table2[] = { + { + .ctl_name =CTL_DEBUG , + .procname ="debug" , + .mode =0555 , + .child = debug_table2 + },
arch/i386/mm/init.c void free_initrd_mem(unsigned long start, unsigned long end) · line 890
Quoted 10 lines
arch/i386/mm/init.c +10
-0+ {} +}; + +static __init int i386_sysctl_init (void ) +{ +register_sysctl_table (debug_root_table2); +return 0 ; +} +__initcall (i386_sysctl_init); +#endif
There's still quite a bit of duplication here.
Perhaps we could move this sysctl stuff into kernel/sysctl.c (under a new CONFIG_EXCEPTION_TRACE (which seems a poor name - maybe CONFIG_REPORT_UNHANDLED_SIGNALS?))
akpm:/usr/src/25> grep -r exception_trace Documentation akpm:/usr/src/25>
ho hum.