From a4cb4b1277a499ebced7f7534d5cfb11a30eb224 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 30 Sep 2014 02:33:59 +0300 Subject: [PATCH] ARM: show short message on segfault kernels on some x86 distros do this, it's pretty useful. --- arch/arm/include/asm/system.h | 1 + arch/arm/kernel/traps.c | 2 +- arch/arm/mm/fault.c | 41 +++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 53785828744c..1344f5f7bc79 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -117,6 +117,7 @@ extern void (*arm_pm_restart)(char str, const char *cmd); #define UDBG_BADABORT (1 << 2) #define UDBG_SEGV (1 << 3) #define UDBG_BUS (1 << 4) +#define UDBG_SEGV_SHORT (1 << 8) extern unsigned int user_debug; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 7d12e732c2be..071772c42e9c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -48,7 +48,7 @@ static const char *handler[]= { void *vectors_page; #ifdef CONFIG_DEBUG_USER -unsigned int user_debug; +unsigned int user_debug = UDBG_SEGV_SHORT; static int __init user_debug_setup(char *str) { diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 4c9c3b063194..ea34eb9d694b 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -152,6 +152,39 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, do_exit(SIGKILL); } +#ifdef CONFIG_DEBUG_USER +static void +print_user_faulter_location(const char *name, struct pt_regs *regs) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + char *p, *t, buf[128]; + + printk(KERN_DEBUG "%s: pc=%08lx", + name, regs->ARM_pc); + + do { + if (!mm) + break; + vma = find_vma(mm, regs->ARM_pc); + if (!vma || !vma->vm_file) + break; + + p = d_path(&vma->vm_file->f_path, buf, sizeof(buf)); + if (IS_ERR(p)) + break; + + t = strrchr(p, '/'); + if (t) + p = t + 1; + + printk(KERN_CONT " (%s+%lx)", p, regs->ARM_pc - vma->vm_start); + } while (0); + + printk(KERN_CONT ", lr=%08lx\n", regs->ARM_lr); +} +#endif + /* * Something tried to access memory that isn't in our memory map.. * User mode accesses just cause a SIGSEGV @@ -164,9 +197,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, struct siginfo si; #ifdef CONFIG_DEBUG_USER + if (user_debug & (UDBG_SEGV | UDBG_SEGV_SHORT)) { + printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x (%s)\n", + tsk->comm, sig, addr, fsr, + (fsr & FSR_WRITE) ? "write" : "read"); + print_user_faulter_location(tsk->comm, regs); + } if (user_debug & UDBG_SEGV) { - printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", - tsk->comm, sig, addr, fsr); show_pte(tsk->mm, addr); show_regs(regs); } -- 2.39.2