aboutsummaryrefslogtreecommitdiff
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
authorChuck Ebbert <76306.1226@compuserve.com>2006-03-23 02:59:30 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-23 07:38:03 -0800
commit4d7d8c82c181711d28c8336108330a9121f5ef07 (patch)
tree2e1537702c1e8447dfbe5b5917333f58f4416c1a /arch/i386/kernel/traps.c
parentb824eb605ccba995fd32c6590aed365f93d48002 (diff)
[PATCH] i386: multi-column stack backtraces
Print stack backtraces in multiple columns, saving screen space. Number of columns is configurable and defaults to one so behavior is backwards-compatible. Also removes the brackets around addresses when printing more that one entry per line so they print as: <address> instead of: [<address>] This helps multiple entries fit better on one line. Original idea by Dave Jones, taken from x86_64. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Dave Jones <davej@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index b814dbdcc91..ee61988f61b 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -112,12 +112,30 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
p < (void *)tinfo + THREAD_SIZE - 3;
}
-static void print_addr_and_symbol(unsigned long addr, char *log_lvl)
+/*
+ * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line.
+ */
+static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
+ int printed)
{
- printk(log_lvl);
+ if (!printed)
+ printk(log_lvl);
+
+#if CONFIG_STACK_BACKTRACE_COLS == 1
printk(" [<%08lx>] ", addr);
+#else
+ printk(" <%08lx> ", addr);
+#endif
print_symbol("%s", addr);
- printk("\n");
+
+ printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
+
+ if (printed)
+ printk(" ");
+ else
+ printk("\n");
+
+ return printed;
}
static inline unsigned long print_context_stack(struct thread_info *tinfo,
@@ -125,20 +143,24 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
char *log_lvl)
{
unsigned long addr;
+ int printed = 0; /* nr of entries already printed on current line */
#ifdef CONFIG_FRAME_POINTER
while (valid_stack_ptr(tinfo, (void *)ebp)) {
addr = *(unsigned long *)(ebp + 4);
- print_addr_and_symbol(addr, log_lvl);
+ printed = print_addr_and_symbol(addr, log_lvl, printed);
ebp = *(unsigned long *)ebp;
}
#else
while (valid_stack_ptr(tinfo, stack)) {
addr = *stack++;
if (__kernel_text_address(addr))
- print_addr_and_symbol(addr, log_lvl);
+ printed = print_addr_and_symbol(addr, log_lvl, printed);
}
#endif
+ if (printed)
+ printk("\n");
+
return ebp;
}