ARM: Dump memory and backtrace as one printk per line
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 11 Oct 2009 14:03:11 +0000 (15:03 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 11 Oct 2009 14:03:11 +0000 (15:03 +0100)
dump_mem and dump_backtrace were both using multiple printk statements
to print each line.  With DEBUG_LL enabled, this causes OOPS to become
very difficult to read.  Solve this by only using one printk per line.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/traps.c

index 467b69ed1021b39fb87848b4009edfef9fb9f1d2..e768fb59b6748907ca4cf3161fdca09ae34ac372 100644 (file)
@@ -50,10 +50,10 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
 #ifdef CONFIG_KALLSYMS
-       printk("[<%08lx>] ", where);
-       print_symbol("(%s) ", where);
-       printk("from [<%08lx>] ", from);
-       print_symbol("(%s)\n", from);
+       char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
+       sprint_symbol(sym1, where);
+       sprint_symbol(sym2, from);
+       printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
 #else
        printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
 #endif
@@ -83,7 +83,7 @@ static int verify_stack(unsigned long sp)
  */
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
-       unsigned long p = bottom & ~31;
+       unsigned long first;
        mm_segment_t fs;
        int i;
 
@@ -97,20 +97,23 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 
        printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
 
-       for (p = bottom & ~31; p < top;) {
-               printk("%04lx: ", p & 0xffff);
+       for (first = bottom & ~31; first < top; first += 32) {
+               unsigned long p;
+               char str[sizeof(" 12345678") * 8 + 1];
 
-               for (i = 0; i < 8; i++, p += 4) {
-                       unsigned int val;
+               memset(str, ' ', sizeof(str));
+               str[sizeof(str) - 1] = '\0';
 
-                       if (p < bottom || p >= top)
-                               printk("         ");
-                       else {
-                               __get_user(val, (unsigned long *)p);
-                               printk("%08x ", val);
+               for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
+                       if (p >= bottom && p < top) {
+                               unsigned long val;
+                               if (__get_user(val, (unsigned long *)p) == 0)
+                                       sprintf(str + i * 9, " %08lx", val);
+                               else
+                                       sprintf(str + i * 9, " ????????");
                        }
                }
-               printk ("\n");
+               printk("%04lx:%s\n", first & 0xffff, str);
        }
 
        set_fs(fs);
@@ -122,6 +125,7 @@ static void dump_instr(struct pt_regs *regs)
        const int thumb = thumb_mode(regs);
        const int width = thumb ? 4 : 8;
        mm_segment_t fs;
+       char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
        int i;
 
        /*
@@ -132,7 +136,6 @@ static void dump_instr(struct pt_regs *regs)
        fs = get_fs();
        set_fs(KERNEL_DS);
 
-       printk("Code: ");
        for (i = -4; i < 1; i++) {
                unsigned int val, bad;
 
@@ -142,13 +145,14 @@ static void dump_instr(struct pt_regs *regs)
                        bad = __get_user(val, &((u32 *)addr)[i]);
 
                if (!bad)
-                       printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
+                       p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
+                                       width, val);
                else {
-                       printk("bad PC value.");
+                       p += sprintf(p, "bad PC value");
                        break;
                }
        }
-       printk("\n");
+       printk("Code: %s\n", str);
 
        set_fs(fs);
 }