Skip to content

Commit

Permalink
[PATCH] i386: multi-column stack backtraces
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chuck Ebbert authored and Linus Torvalds committed Mar 23, 2006
1 parent b824eb6 commit 4d7d8c8
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
9 changes: 9 additions & 0 deletions arch/i386/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ config DEBUG_STACK_USAGE

This option will slow down process creation somewhat.

config STACK_BACKTRACE_COLS
int "Stack backtraces per line" if DEBUG_KERNEL
range 1 3
default 2
help
Selects how many stack backtrace entries per line to display.

This can save screen space when displaying traces.

comment "Page alloc debug is incompatible with Software Suspend on i386"
depends on DEBUG_KERNEL && SOFTWARE_SUSPEND

Expand Down
32 changes: 27 additions & 5 deletions arch/i386/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,33 +112,55 @@ 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,
unsigned long *stack, unsigned long ebp,
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;
}

Expand Down

0 comments on commit 4d7d8c8

Please sign in to comment.