diff options
author | Richard Weinberger <richard@nod.at> | 2011-05-24 20:13:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 11:39:41 -0400 |
commit | 3ef6130ab25a9db6627212d2f6859cc7fc0427ed (patch) | |
tree | 69a4630dc9ac3bf32625e23f63b877a12b0f5adb | |
parent | 4ff4d8d342fe25c4d1106fb0ffdd310a43d0ace0 (diff) |
um: print info about fatal segfaults
Print a short info about fatal segfaults like other archs do.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/um/kernel/trap.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 637c6505dc00..8c7b8823d1f0 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -113,6 +113,27 @@ out_of_memory: | |||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | static void show_segv_info(struct uml_pt_regs *regs) | ||
117 | { | ||
118 | struct task_struct *tsk = current; | ||
119 | struct faultinfo *fi = UPT_FAULTINFO(regs); | ||
120 | |||
121 | if (!unhandled_signal(tsk, SIGSEGV)) | ||
122 | return; | ||
123 | |||
124 | if (!printk_ratelimit()) | ||
125 | return; | ||
126 | |||
127 | printk("%s%s[%d]: segfault at %lx ip %p sp %p error %x", | ||
128 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | ||
129 | tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi), | ||
130 | (void *)UPT_IP(regs), (void *)UPT_SP(regs), | ||
131 | fi->error_code); | ||
132 | |||
133 | print_vma_addr(KERN_CONT " in ", UPT_IP(regs)); | ||
134 | printk(KERN_CONT "\n"); | ||
135 | } | ||
136 | |||
116 | static void bad_segv(struct faultinfo fi, unsigned long ip) | 137 | static void bad_segv(struct faultinfo fi, unsigned long ip) |
117 | { | 138 | { |
118 | struct siginfo si; | 139 | struct siginfo si; |
@@ -141,6 +162,7 @@ void segv_handler(int sig, struct uml_pt_regs *regs) | |||
141 | struct faultinfo * fi = UPT_FAULTINFO(regs); | 162 | struct faultinfo * fi = UPT_FAULTINFO(regs); |
142 | 163 | ||
143 | if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) { | 164 | if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) { |
165 | show_segv_info(regs); | ||
144 | bad_segv(*fi, UPT_IP(regs)); | 166 | bad_segv(*fi, UPT_IP(regs)); |
145 | return; | 167 | return; |
146 | } | 168 | } |
@@ -202,6 +224,8 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
202 | address, ip); | 224 | address, ip); |
203 | } | 225 | } |
204 | 226 | ||
227 | show_segv_info(regs); | ||
228 | |||
205 | if (err == -EACCES) { | 229 | if (err == -EACCES) { |
206 | si.si_signo = SIGBUS; | 230 | si.si_signo = SIGBUS; |
207 | si.si_errno = 0; | 231 | si.si_errno = 0; |