aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJesper Nilsson <jesper.nilsson@axis.com>2010-08-04 11:42:43 -0400
committerJesper Nilsson <jesper.nilsson@axis.com>2010-08-04 12:28:48 -0400
commitb4e8a1813c7d65a7c28a3536da08444c21f2c37b (patch)
tree7b310dfaf31e41d6ff37a0cef2d271c1fca8003e /arch
parent028c1f6817c1ef49c61641dc1ae6c629e5bb32df (diff)
CRIS: Add config for pausing a seg-faulting process
Put it on a wait queue, so we can attach gdb to the process to debug it instead of just killing it. Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/cris/Kconfig.debug6
-rw-r--r--arch/cris/mm/fault.c13
2 files changed, 16 insertions, 3 deletions
diff --git a/arch/cris/Kconfig.debug b/arch/cris/Kconfig.debug
index 0a1d62a23614..0b9a630dc812 100644
--- a/arch/cris/Kconfig.debug
+++ b/arch/cris/Kconfig.debug
@@ -32,4 +32,10 @@ config DEBUG_NMI_OOPS
32 If the system locks up without any debug information you can say Y 32 If the system locks up without any debug information you can say Y
33 here to make it possible to dump an OOPS with an external NMI. 33 here to make it possible to dump an OOPS with an external NMI.
34 34
35config NO_SEGFAULT_TERMINATION
36 bool "Keep segfaulting processes"
37 help
38 Place segfaulting user mode processes on a wait queue instead of
39 delivering a terminating SIGSEGV to allow debugging with gdb.
40
35endmenu 41endmenu
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index a2b4c0b8f0fd..7705cd7cef36 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -7,6 +7,7 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/interrupt.h> 8#include <linux/interrupt.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/wait.h>
10#include <asm/uaccess.h> 11#include <asm/uaccess.h>
11 12
12extern int find_fixup_code(struct pt_regs *); 13extern int find_fixup_code(struct pt_regs *);
@@ -190,14 +191,20 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
190 /* User mode accesses just cause a SIGSEGV */ 191 /* User mode accesses just cause a SIGSEGV */
191 192
192 if (user_mode(regs)) { 193 if (user_mode(regs)) {
194 printk(KERN_NOTICE "%s (pid %d) segfaults for page "
195 "address %08lx at pc %08lx\n",
196 tsk->comm, tsk->pid,
197 address, instruction_pointer(regs));
198#ifdef CONFIG_NO_SEGFAULT_TERMINATION
199 DECLARE_WAIT_QUEUE_HEAD(wq);
200 wait_event_interruptible(wq, 0 == 1);
201#else
193 info.si_signo = SIGSEGV; 202 info.si_signo = SIGSEGV;
194 info.si_errno = 0; 203 info.si_errno = 0;
195 /* info.si_code has been set above */ 204 /* info.si_code has been set above */
196 info.si_addr = (void *)address; 205 info.si_addr = (void *)address;
197 force_sig_info(SIGSEGV, &info, tsk); 206 force_sig_info(SIGSEGV, &info, tsk);
198 printk(KERN_NOTICE "%s (pid %d) segfaults for page " 207#endif
199 "address %08lx at pc %08lx\n",
200 tsk->comm, tsk->pid, address, instruction_pointer(regs));
201 return; 208 return;
202 } 209 }
203 210