diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-07-03 03:24:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-03 18:27:02 -0400 |
commit | 3ac94932a2c859e8c57a8af091fa39334e1c3f23 (patch) | |
tree | 0d1e17d70f1c5b2a52626f96246096688310104d /arch/x86_64/kernel/traps.c | |
parent | e4d919188554a77c798a267e098059bc9aa39726 (diff) |
[PATCH] lockdep: beautify x86_64 stacktraces
Beautify x86_64 stacktraces to be more readable.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 70 |
1 files changed, 31 insertions, 39 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 5a5311d3de0f..02dc155da56f 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -110,28 +110,31 @@ static int kstack_depth_to_print = 12; | |||
110 | static int call_trace = 1; | 110 | static int call_trace = 1; |
111 | 111 | ||
112 | #ifdef CONFIG_KALLSYMS | 112 | #ifdef CONFIG_KALLSYMS |
113 | #include <linux/kallsyms.h> | 113 | # include <linux/kallsyms.h> |
114 | int printk_address(unsigned long address) | 114 | void printk_address(unsigned long address) |
115 | { | 115 | { |
116 | unsigned long offset = 0, symsize; | 116 | unsigned long offset = 0, symsize; |
117 | const char *symname; | 117 | const char *symname; |
118 | char *modname; | 118 | char *modname; |
119 | char *delim = ":"; | 119 | char *delim = ":"; |
120 | char namebuf[128]; | 120 | char namebuf[128]; |
121 | 121 | ||
122 | symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); | 122 | symname = kallsyms_lookup(address, &symsize, &offset, |
123 | if (!symname) | 123 | &modname, namebuf); |
124 | return printk("[<%016lx>]", address); | 124 | if (!symname) { |
125 | if (!modname) | 125 | printk(" [<%016lx>]\n", address); |
126 | return; | ||
127 | } | ||
128 | if (!modname) | ||
126 | modname = delim = ""; | 129 | modname = delim = ""; |
127 | return printk("<%016lx>{%s%s%s%s%+ld}", | 130 | printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n", |
128 | address, delim, modname, delim, symname, offset); | 131 | address, delim, modname, delim, symname, offset, symsize); |
129 | } | 132 | } |
130 | #else | 133 | #else |
131 | int printk_address(unsigned long address) | 134 | void printk_address(unsigned long address) |
132 | { | 135 | { |
133 | return printk("[<%016lx>]", address); | 136 | printk(" [<%016lx>]\n", address); |
134 | } | 137 | } |
135 | #endif | 138 | #endif |
136 | 139 | ||
137 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | 140 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, |
@@ -193,20 +196,14 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
193 | 196 | ||
194 | static int show_trace_unwind(struct unwind_frame_info *info, void *context) | 197 | static int show_trace_unwind(struct unwind_frame_info *info, void *context) |
195 | { | 198 | { |
196 | int i = 11, n = 0; | 199 | int n = 0; |
197 | 200 | ||
198 | while (unwind(info) == 0 && UNW_PC(info)) { | 201 | while (unwind(info) == 0 && UNW_PC(info)) { |
199 | ++n; | 202 | n++; |
200 | if (i > 50) { | 203 | printk_address(UNW_PC(info)); |
201 | printk("\n "); | ||
202 | i = 7; | ||
203 | } else | ||
204 | i += printk(" "); | ||
205 | i += printk_address(UNW_PC(info)); | ||
206 | if (arch_unw_user_mode(info)) | 204 | if (arch_unw_user_mode(info)) |
207 | break; | 205 | break; |
208 | } | 206 | } |
209 | printk("\n"); | ||
210 | return n; | 207 | return n; |
211 | } | 208 | } |
212 | 209 | ||
@@ -224,7 +221,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
224 | int i = 11; | 221 | int i = 11; |
225 | unsigned used = 0; | 222 | unsigned used = 0; |
226 | 223 | ||
227 | printk("\nCall Trace:"); | 224 | printk("\nCall Trace:\n"); |
228 | 225 | ||
229 | if (!tsk) | 226 | if (!tsk) |
230 | tsk = current; | 227 | tsk = current; |
@@ -254,12 +251,6 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
254 | do while (cond) { \ | 251 | do while (cond) { \ |
255 | unsigned long addr = *stack++; \ | 252 | unsigned long addr = *stack++; \ |
256 | if (kernel_text_address(addr)) { \ | 253 | if (kernel_text_address(addr)) { \ |
257 | if (i > 50) { \ | ||
258 | printk("\n "); \ | ||
259 | i = 0; \ | ||
260 | } \ | ||
261 | else \ | ||
262 | i += printk(" "); \ | ||
263 | /* \ | 254 | /* \ |
264 | * If the address is either in the text segment of the \ | 255 | * If the address is either in the text segment of the \ |
265 | * kernel, or in the region which contains vmalloc'ed \ | 256 | * kernel, or in the region which contains vmalloc'ed \ |
@@ -268,20 +259,20 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
268 | * down the cause of the crash will be able to figure \ | 259 | * down the cause of the crash will be able to figure \ |
269 | * out the call path that was taken. \ | 260 | * out the call path that was taken. \ |
270 | */ \ | 261 | */ \ |
271 | i += printk_address(addr); \ | 262 | printk_address(addr); \ |
272 | } \ | 263 | } \ |
273 | } while (0) | 264 | } while (0) |
274 | 265 | ||
275 | for(; ; ) { | 266 | for( ; ; ) { |
276 | const char *id; | 267 | const char *id; |
277 | unsigned long *estack_end; | 268 | unsigned long *estack_end; |
278 | estack_end = in_exception_stack(cpu, (unsigned long)stack, | 269 | estack_end = in_exception_stack(cpu, (unsigned long)stack, |
279 | &used, &id); | 270 | &used, &id); |
280 | 271 | ||
281 | if (estack_end) { | 272 | if (estack_end) { |
282 | i += printk(" <%s>", id); | 273 | printk(" <%s>", id); |
283 | HANDLE_STACK (stack < estack_end); | 274 | HANDLE_STACK (stack < estack_end); |
284 | i += printk(" <EOE>"); | 275 | printk(" <EOE>"); |
285 | stack = (unsigned long *) estack_end[-2]; | 276 | stack = (unsigned long *) estack_end[-2]; |
286 | continue; | 277 | continue; |
287 | } | 278 | } |
@@ -291,11 +282,11 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
291 | (IRQSTACKSIZE - 64) / sizeof(*irqstack); | 282 | (IRQSTACKSIZE - 64) / sizeof(*irqstack); |
292 | 283 | ||
293 | if (stack >= irqstack && stack < irqstack_end) { | 284 | if (stack >= irqstack && stack < irqstack_end) { |
294 | i += printk(" <IRQ>"); | 285 | printk(" <IRQ>"); |
295 | HANDLE_STACK (stack < irqstack_end); | 286 | HANDLE_STACK (stack < irqstack_end); |
296 | stack = (unsigned long *) (irqstack_end[-1]); | 287 | stack = (unsigned long *) (irqstack_end[-1]); |
297 | irqstack_end = NULL; | 288 | irqstack_end = NULL; |
298 | i += printk(" <EOI>"); | 289 | printk(" <EOI>"); |
299 | continue; | 290 | continue; |
300 | } | 291 | } |
301 | } | 292 | } |
@@ -304,6 +295,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
304 | 295 | ||
305 | HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); | 296 | HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); |
306 | #undef HANDLE_STACK | 297 | #undef HANDLE_STACK |
298 | |||
307 | printk("\n"); | 299 | printk("\n"); |
308 | } | 300 | } |
309 | 301 | ||
@@ -337,8 +329,8 @@ static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned | |||
337 | break; | 329 | break; |
338 | } | 330 | } |
339 | if (i && ((i % 4) == 0)) | 331 | if (i && ((i % 4) == 0)) |
340 | printk("\n "); | 332 | printk("\n"); |
341 | printk("%016lx ", *stack++); | 333 | printk(" %016lx", *stack++); |
342 | touch_nmi_watchdog(); | 334 | touch_nmi_watchdog(); |
343 | } | 335 | } |
344 | show_trace(tsk, regs, rsp); | 336 | show_trace(tsk, regs, rsp); |