* [PATCH] Print which shared library/executable faulted in segfault etc. messages v3
@ 2008-01-16 23:15 Andi Kleen
2008-01-17 18:52 ` Jan Engelhardt
0 siblings, 1 reply; 3+ messages in thread
From: Andi Kleen @ 2008-01-16 23:15 UTC (permalink / raw)
To: linux-kernel, mingo, tglx
The previously posted version was missing all the 64bit hunks. Fix
that. Please use over previous version.
-Andi
---
They now look like
hal-resmgr[13791]: segfault at 3c rip 2b9c8caec182 rsp 7fff1e825d30 error 4 in libacl.so.1.1.0[2b9c8caea000+6000]
This makes it easier to pinpoint bugs to specific libraries.
And printing the offset into a mapping also always allows to find the
correct fault point in a library even with randomized mappings. Previously
there was no way to actually find the correct code address inside
the randomized mapping.
Relies on earlier patch to shorten the printk formats.
They are often now longer than 80 characters, but I think that's worth it.
Patch for i386 and x86-64.
[includes fix from Eric Dumazet to check d_path error value]
v3: readd 64bit hunks that got dropped somewhere on the way
Signed-off-by: Andi Kleen <ak@suse.de>
---
arch/x86/kernel/signal_32.c | 7 +++++--
arch/x86/kernel/signal_64.c | 7 +++++--
arch/x86/kernel/traps_32.c | 7 +++++--
arch/x86/mm/fault_32.c | 4 +++-
include/linux/mm.h | 1 +
mm/memory.c | 31 +++++++++++++++++++++++++++++++
6 files changed, 50 insertions(+), 7 deletions(-)
Index: linux/include/linux/mm.h
===================================================================
--- linux.orig/include/linux/mm.h
+++ linux/include/linux/mm.h
@@ -1145,6 +1145,7 @@ extern int randomize_va_space;
#endif
const char * arch_vma_name(struct vm_area_struct *vma);
+void print_vma_addr(char *prefix, unsigned long rip);
struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
Index: linux/mm/memory.c
===================================================================
--- linux.orig/mm/memory.c
+++ linux/mm/memory.c
@@ -2746,3 +2746,34 @@ int access_process_vm(struct task_struct
return buf - old_buf;
}
+
+/*
+ * Print the name of a VMA.
+ */
+void print_vma_addr(char *prefix, unsigned long ip)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, ip);
+ if (vma && vma->vm_file) {
+ struct file *f = vma->vm_file;
+ char *buf = (char *)__get_free_page(GFP_KERNEL);
+ if (buf) {
+ char *p, *s;
+
+ p = d_path(f->f_dentry, f->f_vfsmnt, buf, PAGE_SIZE);
+ if (IS_ERR(p))
+ p = "?";
+ s = strrchr(p, '/');
+ if (s)
+ p = s+1;
+ printk("%s%s[%lx+%lx]", prefix, p,
+ vma->vm_start,
+ vma->vm_end - vma->vm_start);
+ free_page((unsigned long)buf);
+ }
+ }
+ up_read(¤t->mm->mmap_sem);
+}
Index: linux/arch/x86/kernel/signal_32.c
===================================================================
--- linux.orig/arch/x86/kernel/signal_32.c
+++ linux/arch/x86/kernel/signal_32.c
@@ -198,12 +198,15 @@ asmlinkage int sys_sigreturn(unsigned lo
return ax;
badframe:
- if (show_unhandled_signals && printk_ratelimit())
+ if (show_unhandled_signals && printk_ratelimit()) {
printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx"
- " sp:%lx oeax:%lx\n",
+ " sp:%lx oeax:%lx",
task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
current->comm, task_pid_nr(current), frame, regs->ip,
regs->sp, regs->orig_ax);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
force_sig(SIGSEGV, current);
return 0;
Index: linux/arch/x86/kernel/signal_64.c
===================================================================
--- linux.orig/arch/x86/kernel/signal_64.c
+++ linux/arch/x86/kernel/signal_64.c
@@ -481,9 +481,12 @@ do_notify_resume(struct pt_regs *regs, v
void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
{
struct task_struct *me = current;
- if (show_unhandled_signals && printk_ratelimit())
- printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx\n",
+ if (show_unhandled_signals && printk_ratelimit()) {
+ printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
force_sig(SIGSEGV, me);
}
Index: linux/arch/x86/kernel/traps_32.c
===================================================================
--- linux.orig/arch/x86/kernel/traps_32.c
+++ linux/arch/x86/kernel/traps_32.c
@@ -608,11 +608,14 @@ void __kprobes do_general_protection(str
current->thread.error_code = error_code;
current->thread.trap_no = 13;
if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
- printk_ratelimit())
+ printk_ratelimit()) {
printk(KERN_INFO
- "%s[%d] general protection ip:%lx sp:%lx error:%lx\n",
+ "%s[%d] general protection ip:%lx sp:%lx error:%lx",
current->comm, task_pid_nr(current),
regs->ip, regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
force_sig(SIGSEGV, current);
return;
Index: linux/arch/x86/mm/fault_32.c
===================================================================
--- linux.orig/arch/x86/mm/fault_32.c
+++ linux/arch/x86/mm/fault_32.c
@@ -518,11 +518,13 @@ bad_area_nosemaphore:
#ifdef CONFIG_X86_32
"%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx\n",
#else
- "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n",
+ "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
#endif
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, task_pid_nr(tsk), address, regs->ip,
regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
}
tsk->thread.cr2 = address;
/* Kernel addresses are always protection faults */
Index: linux/arch/x86/kernel/traps_64.c
===================================================================
--- linux.orig/arch/x86/kernel/traps_64.c
+++ linux/arch/x86/kernel/traps_64.c
@@ -647,11 +647,14 @@ static void __kprobes do_trap(int trapnr
tsk->thread.trap_no = trapnr;
if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
- printk_ratelimit())
+ printk_ratelimit()) {
printk(KERN_INFO
- "%s[%d] trap %s ip:%lx sp:%lx error:%lx\n",
+ "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
tsk->comm, tsk->pid, str,
regs->ip, regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
if (info)
force_sig_info(signr, info, tsk);
@@ -745,11 +748,14 @@ asmlinkage void __kprobes do_general_pro
tsk->thread.trap_no = 13;
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
- printk_ratelimit())
+ printk_ratelimit()) {
printk(KERN_INFO
- "%s[%d] general protection ip:%lx sp:%lx error:%lx\n",
+ "%s[%d] general protection ip:%lx sp:%lx error:%lx",
tsk->comm, tsk->pid,
regs->ip, regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
force_sig(SIGSEGV, tsk);
return;
Index: linux/arch/x86/mm/fault_64.c
===================================================================
--- linux.orig/arch/x86/mm/fault_64.c
+++ linux/arch/x86/mm/fault_64.c
@@ -556,11 +556,13 @@ bad_area_nosemaphore:
#ifdef CONFIG_X86_32
"%s%s[%d]: segfault at %08lx ip %08lx sp %08lx error %lx\n",
#else
- "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n",
+ "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
#endif
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, task_pid_nr(tsk), address, regs->ip,
regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
}
tsk->thread.cr2 = address;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Print which shared library/executable faulted in segfault etc. messages v3
2008-01-16 23:15 [PATCH] Print which shared library/executable faulted in segfault etc. messages v3 Andi Kleen
@ 2008-01-17 18:52 ` Jan Engelhardt
2008-01-17 19:44 ` Andi Kleen
0 siblings, 1 reply; 3+ messages in thread
From: Jan Engelhardt @ 2008-01-17 18:52 UTC (permalink / raw)
To: Andi Kleen; +Cc: linux-kernel, mingo, tglx
On Jan 17 2008 00:15, Andi Kleen wrote:
>
>The previously posted version was missing all the 64bit hunks. Fix
>that. Please use over previous version.
>
>They now look like
>
>hal-resmgr[13791]: segfault at 3c rip 2b9c8caec182 rsp 7fff1e825d30
>error 4 in libacl.so.1.1.0[2b9c8caea000+6000]
Can this also be done for executables?
>This makes it easier to pinpoint bugs to specific libraries.
[But it may very well mean improper usage (e.g. passing NULL where
NULL is definitely not expected) on behalf of the library user ;-)]
>And printing the offset into a mapping also always allows to find
>the correct fault point in a library even with randomized mappings.
>Previously there was no way to actually find the correct code
>address inside the randomized mapping.
Previously, one had to ptrace the process, wait for the crash to
happen, then inspect /proc/XXX/maps and calculate the address. It's
not like developers were left in the dark with random mappings.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Print which shared library/executable faulted in segfault etc. messages v3
2008-01-17 18:52 ` Jan Engelhardt
@ 2008-01-17 19:44 ` Andi Kleen
0 siblings, 0 replies; 3+ messages in thread
From: Andi Kleen @ 2008-01-17 19:44 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: linux-kernel, mingo, tglx
> >hal-resmgr[13791]: segfault at 3c rip 2b9c8caec182 rsp 7fff1e825d30
> >error 4 in libacl.so.1.1.0[2b9c8caea000+6000]
>
> Can this also be done for executables?
This is done for executables.
-Andi
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-01-17 19:45 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-16 23:15 [PATCH] Print which shared library/executable faulted in segfault etc. messages v3 Andi Kleen
2008-01-17 18:52 ` Jan Engelhardt
2008-01-17 19:44 ` Andi Kleen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox