x86: print which shared library/executable faulted in segfault etc. messages v3

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.

[includes fix from Eric Dumazet to check d_path error value]

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Andi Kleen 2008-01-30 13:33:18 +01:00 коммит произвёл Ingo Molnar
Родитель d3432896da
Коммит 03252919b7
8 изменённых файлов: 63 добавлений и 12 удалений

Просмотреть файл

@ -198,12 +198,15 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
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;

Просмотреть файл

@ -484,9 +484,12 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
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);
}

Просмотреть файл

@ -609,11 +609,14 @@ void __kprobes do_general_protection(struct pt_regs * regs,
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;

Просмотреть файл

@ -642,11 +642,14 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
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);
@ -741,11 +744,14 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
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;

Просмотреть файл

@ -514,11 +514,13 @@ bad_area_nosemaphore:
#ifdef CONFIG_X86_32
"%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
#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 */

Просмотреть файл

@ -552,11 +552,13 @@ bad_area_nosemaphore:
#ifdef CONFIG_X86_32
"%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
#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;

Просмотреть файл

@ -1146,6 +1146,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);

Просмотреть файл

@ -2754,3 +2754,34 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
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(&current->mm->mmap_sem);
}