diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-11 10:03:11 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-11 10:03:11 -0400 |
commit | d191fe093f4494e0220f11f4ef2068b9581357b5 (patch) | |
tree | ea9e163e49ad925295c2a8061e69fc33bde3c2c6 /arch/arm | |
parent | ebd00c08e28a0ab4dcb715d222214625fff6d62a (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>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/traps.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 467b69ed1021..e768fb59b674 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); | |||
50 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | 50 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) |
51 | { | 51 | { |
52 | #ifdef CONFIG_KALLSYMS | 52 | #ifdef CONFIG_KALLSYMS |
53 | printk("[<%08lx>] ", where); | 53 | char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN]; |
54 | print_symbol("(%s) ", where); | 54 | sprint_symbol(sym1, where); |
55 | printk("from [<%08lx>] ", from); | 55 | sprint_symbol(sym2, from); |
56 | print_symbol("(%s)\n", from); | 56 | printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2); |
57 | #else | 57 | #else |
58 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); | 58 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); |
59 | #endif | 59 | #endif |
@@ -83,7 +83,7 @@ static int verify_stack(unsigned long sp) | |||
83 | */ | 83 | */ |
84 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top) | 84 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top) |
85 | { | 85 | { |
86 | unsigned long p = bottom & ~31; | 86 | unsigned long first; |
87 | mm_segment_t fs; | 87 | mm_segment_t fs; |
88 | int i; | 88 | int i; |
89 | 89 | ||
@@ -97,20 +97,23 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) | |||
97 | 97 | ||
98 | printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); | 98 | printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); |
99 | 99 | ||
100 | for (p = bottom & ~31; p < top;) { | 100 | for (first = bottom & ~31; first < top; first += 32) { |
101 | printk("%04lx: ", p & 0xffff); | 101 | unsigned long p; |
102 | char str[sizeof(" 12345678") * 8 + 1]; | ||
102 | 103 | ||
103 | for (i = 0; i < 8; i++, p += 4) { | 104 | memset(str, ' ', sizeof(str)); |
104 | unsigned int val; | 105 | str[sizeof(str) - 1] = '\0'; |
105 | 106 | ||
106 | if (p < bottom || p >= top) | 107 | for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { |
107 | printk(" "); | 108 | if (p >= bottom && p < top) { |
108 | else { | 109 | unsigned long val; |
109 | __get_user(val, (unsigned long *)p); | 110 | if (__get_user(val, (unsigned long *)p) == 0) |
110 | printk("%08x ", val); | 111 | sprintf(str + i * 9, " %08lx", val); |
112 | else | ||
113 | sprintf(str + i * 9, " ????????"); | ||
111 | } | 114 | } |
112 | } | 115 | } |
113 | printk ("\n"); | 116 | printk("%04lx:%s\n", first & 0xffff, str); |
114 | } | 117 | } |
115 | 118 | ||
116 | set_fs(fs); | 119 | set_fs(fs); |
@@ -122,6 +125,7 @@ static void dump_instr(struct pt_regs *regs) | |||
122 | const int thumb = thumb_mode(regs); | 125 | const int thumb = thumb_mode(regs); |
123 | const int width = thumb ? 4 : 8; | 126 | const int width = thumb ? 4 : 8; |
124 | mm_segment_t fs; | 127 | mm_segment_t fs; |
128 | char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; | ||
125 | int i; | 129 | int i; |
126 | 130 | ||
127 | /* | 131 | /* |
@@ -132,7 +136,6 @@ static void dump_instr(struct pt_regs *regs) | |||
132 | fs = get_fs(); | 136 | fs = get_fs(); |
133 | set_fs(KERNEL_DS); | 137 | set_fs(KERNEL_DS); |
134 | 138 | ||
135 | printk("Code: "); | ||
136 | for (i = -4; i < 1; i++) { | 139 | for (i = -4; i < 1; i++) { |
137 | unsigned int val, bad; | 140 | unsigned int val, bad; |
138 | 141 | ||
@@ -142,13 +145,14 @@ static void dump_instr(struct pt_regs *regs) | |||
142 | bad = __get_user(val, &((u32 *)addr)[i]); | 145 | bad = __get_user(val, &((u32 *)addr)[i]); |
143 | 146 | ||
144 | if (!bad) | 147 | if (!bad) |
145 | printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); | 148 | p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", |
149 | width, val); | ||
146 | else { | 150 | else { |
147 | printk("bad PC value."); | 151 | p += sprintf(p, "bad PC value"); |
148 | break; | 152 | break; |
149 | } | 153 | } |
150 | } | 154 | } |
151 | printk("\n"); | 155 | printk("Code: %s\n", str); |
152 | 156 | ||
153 | set_fs(fs); | 157 | set_fs(fs); |
154 | } | 158 | } |