Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03252919 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar
Browse files

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: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent d3432896
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -198,12 +198,15 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
	return ax;
	return ax;


badframe:
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"
		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,
		    task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
		    current->comm, task_pid_nr(current), frame, regs->ip,
		    current->comm, task_pid_nr(current), frame, regs->ip,
		    regs->sp, regs->orig_ax);
		    regs->sp, regs->orig_ax);
		print_vma_addr(" in ", regs->ip);
		printk("\n");
	}


	force_sig(SIGSEGV, current);
	force_sig(SIGSEGV, current);
	return 0;
	return 0;
+5 −2
Original line number Original line Diff line number Diff line
@@ -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)
void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
{ 
{ 
	struct task_struct *me = current; 
	struct task_struct *me = current; 
	if (show_unhandled_signals && printk_ratelimit())
	if (show_unhandled_signals && printk_ratelimit()) {
		printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx\n",
		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);
	       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); 
	force_sig(SIGSEGV, me); 
} 
} 
+5 −2
Original line number Original line Diff line number Diff line
@@ -609,11 +609,14 @@ void __kprobes do_general_protection(struct pt_regs * regs,
	current->thread.error_code = error_code;
	current->thread.error_code = error_code;
	current->thread.trap_no = 13;
	current->thread.trap_no = 13;
	if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
	if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
	    printk_ratelimit())
	    printk_ratelimit()) {
		printk(KERN_INFO
		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),
		    current->comm, task_pid_nr(current),
		    regs->ip, regs->sp, error_code);
		    regs->ip, regs->sp, error_code);
		print_vma_addr(" in ", regs->ip);
		printk("\n");
	}


	force_sig(SIGSEGV, current);
	force_sig(SIGSEGV, current);
	return;
	return;
+10 −4
Original line number Original line Diff line number Diff line
@@ -642,11 +642,14 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
		tsk->thread.trap_no = trapnr;
		tsk->thread.trap_no = trapnr;


		if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
		if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
		    printk_ratelimit())
		    printk_ratelimit()) {
			printk(KERN_INFO
			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,
			       tsk->comm, tsk->pid, str,
			       regs->ip, regs->sp, error_code);
			       regs->ip, regs->sp, error_code);
			print_vma_addr(" in ", regs->ip);
			printk("\n");
		}


		if (info)
		if (info)
			force_sig_info(signr, info, tsk);
			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;
		tsk->thread.trap_no = 13;


		if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
		if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
		    printk_ratelimit())
		    printk_ratelimit()) {
			printk(KERN_INFO
			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,
			       tsk->comm, tsk->pid,
			       regs->ip, regs->sp, error_code);
			       regs->ip, regs->sp, error_code);
			print_vma_addr(" in ", regs->ip);
			printk("\n");
		}


		force_sig(SIGSEGV, tsk);
		force_sig(SIGSEGV, tsk);
		return;
		return;
+3 −1
Original line number Original line Diff line number Diff line
@@ -514,11 +514,13 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_32
			"%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
			"%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
#else
#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
#endif
			task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
			task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
			tsk->comm, task_pid_nr(tsk), address, regs->ip,
			tsk->comm, task_pid_nr(tsk), address, regs->ip,
			regs->sp, error_code);
			regs->sp, error_code);
			print_vma_addr(" in ", regs->ip);
			printk("\n");
		}
		}
		tsk->thread.cr2 = address;
		tsk->thread.cr2 = address;
		/* Kernel addresses are always protection faults */
		/* Kernel addresses are always protection faults */
Loading