From: masouds@google.com (Masoud Asgharifard Sharbiani)
To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org
Subject: [PATCH] Make i386 kernel show the segfaults in kernel dmesg, like x86_64.
Date: Tue, 5 Jun 2007 14:52:44 -0700 [thread overview]
Message-ID: <20070605215242.GA16967@google.com> (raw)
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.
Signed-off-by: Masoud Sharbiani <masouds@google.com>
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 29d7d61..6aa56db 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -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);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index b22ce8d..a300ff8 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -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
+
+
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index bfb62a1..863189a 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -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)
{
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 85255db..4fad501 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -75,8 +75,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
extern 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;
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 9a5eac5..1ebe715 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -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
diff --git a/kernel/signal.c b/kernel/signal.c
index 364fc95..6ae6aac 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -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)
next reply other threads:[~2007-06-05 21:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-05 21:52 Masoud Asgharifard Sharbiani [this message]
2007-06-07 22:41 ` [PATCH] Make i386 kernel show the segfaults in kernel dmesg, like x86_64 Andrew Morton
[not found] <fa.FB3wQKN6ltiEi81XcB14YVcLGgE@ifi.uio.no>
2007-06-08 2:04 ` Robert Hancock
2007-06-08 2:34 ` Andrew Morton
2007-06-08 3:50 ` Masoud Sharbiani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070605215242.GA16967@google.com \
--to=masouds@google.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox