summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-10-11 15:03:11 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-10-11 15:03:11 +0100
commitd191fe093f4494e0220f11f4ef2068b9581357b5 (patch)
treeea9e163e49ad925295c2a8061e69fc33bde3c2c6
parentebd00c08e28a0ab4dcb715d222214625fff6d62a (diff)
ARM: Dump memory and backtrace as one printk per line
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>
-rw-r--r--arch/arm/kernel/traps.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 467b69ed102..e768fb59b67 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -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);
}