RFC. User space backtrace on segv
PATCH 1/1 RFC. User space backtrace on segv
Hi,
I hacked up this little patch to dump the stack and attempt to generate a back-trace for errant user-space tasks.
What:
Generates a back-trace of the user application on (in this case) a segv caused by an unaligned access. This particular patch is against 2.4.22 on the SH which is what I'm working with but there no reason it couldn't be more generalised.
How:
Its not the most intelligent approach as it basically walks up the stack reading values and seeing if the address corresponds to one of the processes executable VMA's. If it matches it assumes its the return address treats that section as a "frame"
Why:
I work with embedded systems and for a myriad of reasons doing a full core dump of the crashing task is a pain. Often just knowing the immediate call stack and local variables is enough to look at what went wrong with objdump -S.
Questions:
Have I replicated anything that is already hidden in the code base? Would this be useful (as a CONFIG_ option) for embedded systems?
Signature · 6 lines
Alex, Kernel Hacker: http://www.bennee.com/~alex/ "Mach was the greatest intellectual fraud in the last ten years." "What about X?" "I said `intellectual'." ;login, 9/1990
Quoted 5 lines · Alex Bennee
Hi,
I hacked up this little patch to dump the stack and attempt to generate a back-trace for errant user-space tasks.
<snip>
It would of been helpful if I'd actually attached the patch. Doh!
Signature · 4 lines
Alex, Kernel Hacker: http://www.bennee.com/~alex/ Test input for validity and plausibility. - The Elements of Programming Style (Kernighan & Plaugher)
Index: arch/sh/kernel/traps.c
===================================================================
RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/traps.c,v retrieving revision 1.1.1.1.2.5
sh/kernel/traps.c +111 -1
@@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.1.1.1.2.4 2002/05/10 17:58:54 jzs Exp $ +/* $Id: traps.c,v 1.1.1.1.2.5 2003/10/23 22:08:56 yoshii Exp $ * * linux/arch/sh/traps.c *
@@ -32,6 +32,8 @@#include <asm/atomic.h> #include <asm/processor.h> +void dump_user_task (struct task_struct *tsk,struct pt_regs *regs); +#ifdef CONFIG_SH_KGDB #include <asm/kgdb.h> #define CHK_REMOTE_DEBUG (regs) \
@@ -114,6 +116,7 @@ regs->pc = fixup;return 0 ; } +printk (KERN_ALERT "no fixup: pid=%d pc=0x%lx\n" ,current->pid,current->thread.pc);die (str, regs, err); }return -EFAULT ;
@@ -515,6 +518,7 @@ uspace_segv:printk (KERN_NOTICE "Killing process \"%s\" due to unaligned access\n" , current->comm); +dump_user_task (current, regs);force_sig (SIGSEGV , current); }else {if (regs->pc &1 )
@@ -605,6 +609,11 @@ : "memory"); } +/* +** This attempts to do a backtrace through the +** kernel-space stack (therfor shows the kernel backtrace) +*/ +void show_task (unsigned long *sp) {unsigned long *stack, addr;
@@ -653,3 +662,104 @@ {show_task ((unsigned long *)tsk->thread.sp); } + + +/* +** Generate Userspace Backtrace +** +** In theory this shouldn't be needed as when a userspace task +** dies you can generate a core dump. However for embedded systems it +** may just be easier to dump the registers and the user-stack +*/ + +void dump_user_frame (int frame,unsigned long *start_addr,unsigned long *end_addr) +{ +unsigned long addr; + +#if 0 +printk (KERN_ALERT "Frame %d (%p->%p)\n" , + frame, start_addr, end_addr); +#endif + +printk (KERN_ALERT "Frame %2d: " , frame); + +do { +get_user (addr, start_addr); +printk ("0x%08lx " , addr); + start_addr++; + }while (start_addr<end_addr); + +get_user (addr, end_addr); +printk (": <0x%08lx>\n" ,addr); +} + +void dump_user_task (struct task_struct *tsk,struct pt_regs *regs) +{ +unsigned long start_code, end_code, *sp; +unsigned long *start_frame, *end_frame; +int frame=0 ; + +if (!user_mode (regs)) { +printk (KERN_ALERT "dump_user_task: not in userspace" ); +return ; + } + +printk (KERN_ALERT "dump_user_task (%p): %s, pid %d, pc 0x%lx\n" , + tsk, tsk->comm, tsk->pid, regs->pc); + +show_regs (regs); + +/* +* Find the start and end code addresses from the +* process descriptor. We shall need this to work +* out if values on the stack are return addresses +*/ + start_code = tsk->mm->start_code; + end_code = tsk->mm->end_code; + sp = (unsigned long *) regs->regs[14 ]; + +printk (KERN_ALERT "start_code=0x%lx, end_code=0x%lx, sp=%p/0x%lx\n" , + start_code, + end_code, + sp, tsk->mm->start_stack); + +/* +* R14 points at the bottom of the stack frame (it grows down) +* which include the local variables and return addresses. +* +* We simply follow the stack back up, a long word at a time +* printing anything that falls in a vma with execute privalages +*/ + + start_frame = sp; + +do { +unsigned long addr; +struct vm_area_struct * vma; + +get_user (addr, sp); + +if (addr==0 ) + vma =NULL ; +else + vma =find_vma (tsk->mm, addr); + +if (vma) { +if (vma->vm_flags&VM_EXECUTABLE ) + { +#if 0 +printk (KERN_ALERT "addr %p, vma 0x%lx (0x%lx->0x%lx), flags 0x%x\n" , + addr, vma, vma->vm_start, vma->vm_end, vma->vm_flags); +#endif + end_frame = sp; +dump_user_frame (frame, start_frame, end_frame); + frame++; + start_frame = end_frame; + start_frame++; + } + } + sp++; + }while ((unsigned long )sp<tsk->mm->start_stack && frame<4 ); + +} +
Quoted 7 lines · Alex Bennee
Quoted 5 lines · Alex Bennee
Hi,
I hacked up this little patch to dump the stack and attempt to generate a back-trace for errant user-space tasks.
<snip>
Note that there already is similar functionality on s390, possibly on other architectures as well. In kernel/sysctl.c, there is code to make the behavior run-time selectable. The sysctl is currently called KERN_S390_USER_DEBUG_LOGGING and compiled in only for s390, but it might be a good idea to define this in an architecture independent way, e.g. with a config option that is always selected on s390, sh and possibly other archs.
Arnd <><
Quoted 26 lines · Alex Bennee
Hi,
I hacked up this little patch to dump the stack and attempt to generate a back-trace for errant user-space tasks.
What:
Generates a back-trace of the user application on (in this case) a segv caused by an unaligned access. This particular patch is against 2.4.22 on the SH which is what I'm working with but there no reason it couldn't be more generalised.
How:
Its not the most intelligent approach as it basically walks up the stack reading values and seeing if the address corresponds to one of the processes executable VMA's. If it matches it assumes its the return address treats that section as a "frame"
Why:
I work with embedded systems and for a myriad of reasons doing a full core dump of the crashing task is a pain. Often just knowing the immediate call stack and local variables is enough to look at what went wrong with objdump -S.
Quoted 5 lines
Questions:
Have I replicated anything that is already hidden in the code base? Would this be useful (as a
CONFIG_option) for embedded systems?
IIRC, there is already a backtrace function defined for most arches in the c library. in execinfo.h there is a family of backtrace functions that can unwind the stack fairly well for most arches, and store the trace in a post SIGSEGV-safe fashion.
Neil
Signature · 8 lines
/*************************************************** *Neil Horman *Software Engineer *Red Hat, Inc. *[email protected] *gpg keyid: 1024D / 0x92A74FA1 *http://pgp.mit.edu ***************************************************/
RTC (real time clock) question about sh4 7760
Hi All,
I'm porting linux sh onLogic PD lsh7760-10 board.
The sh4 7760 doesn't have an on chip RTC (while other sh4 processors does), and the board I'm working on seems to have no RTC (maybe I2C bus connected). So in such application I think there is no RTC available; what is the best way to describe this? I think to write rtc.c rtc.h modules and write the related funcions doing nothing.
Is it correct?
Thanks a lot
Fabio
Quoted 1 line · Neil Horman
IIRC, there is already a backtrace function defined for most arches in the c library. in
execinfo.hthere is a family of backtrace functions that can unwind the stack fairly well for most arches, and store the trace in a post SIGSEGV-safe fashion.
I've some info on this here:
http://www.pixelbeat.org/libs/backtrace.c
Pádraig.