Greg Ungerer
Sun, 27 Apr 2008 23:15:35 -0700
Hi Sebastian, Sebastian Siewior wrote:
With this patch and CONFIG_FRAME_POINTER=y CONFIG_KALLSYMS=y The backtrace shows resolved function names and their numeric address. Signed-off-by: Sebastian Siewior <[EMAIL PROTECTED]> --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c @@ -28,6 +28,7 @@ #include <linux/linkage.h> #include <linux/init.h> #include <linux/ptrace.h> +#include <linux/kallsyms.h>#include <asm/setup.h>#include <asm/fpu.h> @@ -102,54 +103,47 @@ asmlinkage void buserr_c(struct frame *f force_sig(SIGSEGV, current); }-int kstack_depth_to_print = 48;-void show_stack(struct task_struct *task, unsigned long *stack)+static void __show_stack(struct task_struct *task, unsigned long *stack) { unsigned long *endstack, addr; - extern char _start, _etext; + unsigned long *last_stack; int i;- if (!stack) {- if (task) - stack = (unsigned long *)task->thread.ksp; - else - stack = (unsigned long *)&stack; - } + if (!stack) + stack = (unsigned long *)task->thread.ksp;addr = (unsigned long) stack;endstack = (unsigned long *) PAGE_ALIGN(addr);printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);for (i = 0; i < kstack_depth_to_print; i++) { - if (stack + 1 > endstack) + if (stack + 1 + i > endstack) break; if (i % 8 == 0) printk("\n" KERN_EMERG " "); - printk(" %08lx", *stack++); + printk(" %08lx", *(stack + i)); } printk("\n");- printk(KERN_EMERG "Call Trace:");- i = 0; - while (stack + 1 <= endstack) { - addr = *stack++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (((addr >= (unsigned long) &_start) && - (addr <= (unsigned long) &_etext))) { - if (i % 4 == 0) - printk("\n" KERN_EMERG " "); - printk(" [<%08lx>]", addr); - i++; - } +#ifdef CONFIG_FRAME_POINTER + printk(KERN_EMERG "Call Trace:\n"); +#else + printk(KERN_EMERG "The following call trace is a joke. " + "Enable CONFIG_FRAME_POINTER in Kernel Kconfig for usefull " + "output.\n"); +#endif + + last_stack = stack - 1; + while (stack <= endstack && stack > last_stack) { + + addr = *(stack +1); + printk(KERN_EMERG " [%08lx] ", addr); + print_symbol(KERN_CONT "%s\n", addr); + + last_stack = stack; + stack = (unsigned long *)*stack; } printk("\n"); }
I don't like this specific chunk. Seems pointless even trying to
do a symbolic call trace if CONFIG_FRAME_POINTER is disabled.
So I would rather do:
> #ifdef CONFIG_FRAME_POINTER
> printk(KERN_EMERG "Call Trace:\n");
>
> last_stack = stack - 1;
> while (stack <= endstack && stack > last_stack) {
>
> addr = *(stack +1);
> printk(KERN_EMERG " [%08lx] ", addr);
> print_symbol(KERN_CONT "%s\n", addr);
>
> last_stack = stack;
> stack = (unsigned long *)*stack;
154a144,146
> #else
> printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic
call trace\n");
> #endif Otherwise I am happy with it. Regards Greg
@@ -298,19 +292,47 @@ asmlinkage void set_esp0(unsigned long s current->thread.esp0 = ssp; }-/* * The architecture-independent backtrace generator */ void dump_stack(void) { - unsigned long stack; - - show_stack(current, &stack); + /* + * We need frame pointers for this little trick, which works as follows: + * + * +------------+ 0x00 + * | Next SP | -> 0x0c + * +------------+ 0x04 + * | Caller | + * +------------+ 0x08 + * | Local vars | -> our stack var + * +------------+ 0x0c + * | Next SP | -> 0x18, that is what we pass to show_stack() + * +------------+ 0x10 + * | Caller | + * +------------+ 0x14 + * | Local vars | + * +------------+ 0x18 + * | ... | + * +------------+ + */ + + unsigned long *stack; + + stack = (unsigned long *)&stack; + stack++; + __show_stack(current, stack); } - EXPORT_SYMBOL(dump_stack);+void show_stack(struct task_struct *task, unsigned long *stack)+{ + if (!stack && !task) + dump_stack(); + else + __show_stack(task, stack); +} + #ifdef CONFIG_M68KFPU_EMU asmlinkage void fpemu_signal(int signal, int code, void *addr) {
-- ------------------------------------------------------------------------ Greg Ungerer -- Chief Software Dude EMAIL: [EMAIL PROTECTED] Secure Computing Corporation PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com _______________________________________________ uClinux-dev mailing list uClinux-dev@uclinux.org http://mailman.uclinux.org/mailman/listinfo/uclinux-dev This message was resent by uclinux-dev@uclinux.org To unsubscribe see: http://mailman.uclinux.org/mailman/options/uclinux-dev