[PATCH] x86-64: improve the format of stack dumps



Improve the format of stack dumps for x86-64.
* Single column of stack entries. (similar to other arches)
* Print the offset in hexadecimal instead of decimal! (similar to other arches)
* Print the size of the routines as well. (similar to other arches)
* No white line after RIP.
* No duplicate register dump on RIP line.
* No white line after register dump.
* Formatted/lined up dump of the stacks.

For example:

SysRq : Show Regs
CPU 0:
Modules linked in: i2c_dev i2c_core
Pid: 0, comm: swapper Not tainted 2.6.16-rc2-git #34
RIP: 0010:[<ffffffff801096b1>] mwait_idle+0x3c/0x53
RSP: 0018:ffffffff8059bf70 EFLAGS: 00000246
RAX: 0000000000000000 RBX: ffffffff80109675 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff8052d698
RBP: ffffffff8059bf70 R08: 00000000ffffffff R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff805d7184
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffffffff8058d000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002abae842f000 CR3: 00000000763b3000 CR4: 00000000000006e0
Call Trace:
[<ffffffff80109654>] cpu_idle+0x6c/0x8d
[<ffffffff8010802b>] rest_init+0x2b/0x31
[<ffffffff8059c89a>] start_kernel+0x1dc/0x1de
[<ffffffff8059c2a9>] _sinittext+0x2a9/0x2b0

Signed-off-by: Luben Tuikov <ltuikov@xxxxxxxxx>

arch/x86_64/kernel/process.c | 4 +-
arch/x86_64/kernel/traps.c | 75 +++++++++++++------------------------------
include/linux/kallsyms.h | 7 ++--
kernel/kallsyms.c | 4 +-
4 files changed, 32 insertions(+), 58 deletions(-)

diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 8ded407..6a29b0e 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -302,9 +302,9 @@ void __show_regs(struct pt_regs * regs)
system_utsname.release,
(int)strcspn(system_utsname.version, " "),
system_utsname.version);
- printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
+ printk("RIP: %04lx:", regs->cs & 0xffff);
printk_address(regs->rip);
- printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
+ printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
regs->eflags);
printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
regs->rax, regs->rbx, regs->rcx);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 8bb0aed..842925e 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/nmi.h>
#include <linux/kprobes.h>
+#include <linux/kallsyms.h>

#include <asm/system.h>
#include <asm/uaccess.h>
@@ -92,30 +93,15 @@ static inline void conditional_sti(struc

static int kstack_depth_to_print = 10;

-#ifdef CONFIG_KALLSYMS
-#include <linux/kallsyms.h>
-int printk_address(unsigned long address)
-{
- unsigned long offset = 0, symsize;
- const char *symname;
- char *modname;
- char *delim = ":";
- char namebuf[128];
-
- symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
- if (!symname)
- return printk("[<%016lx>]", address);
- if (!modname)
- modname = delim = "";
- return printk("<%016lx>{%s%s%s%s%+ld}",
- address,delim,modname,delim,symname,offset);
-}
-#else
-int printk_address(unsigned long address)
-{
- return printk("[<%016lx>]", address);
-}
-#endif
+int printk_address(unsigned long addr)
+{
+ int i = 0;
+ i += printk("[<%08lx>] ", addr);
+ i += __print_symbol("%s", addr);
+ i += printk("\n");
+
+ return i;
+}

static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
unsigned *usedp, const char **idp)
@@ -185,43 +171,29 @@ void show_trace(unsigned long *stack)
{
const unsigned cpu = safe_smp_processor_id();
unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
- int i;
unsigned used = 0;

- printk("\nCall Trace:");
+ printk("Call Trace:\n");

-#define HANDLE_STACK(cond) \
- do while (cond) { \
- unsigned long addr = *stack++; \
- if (kernel_text_address(addr)) { \
- if (i > 50) { \
- printk("\n "); \
- i = 0; \
- } \
- else \
- i += printk(" "); \
- /* \
- * If the address is either in the text segment of the \
- * kernel, or in the region which contains vmalloc'ed \
- * memory, it *may* be the address of a calling \
- * routine; if so, print it so that someone tracing \
- * down the cause of the crash will be able to figure \
- * out the call path that was taken. \
- */ \
- i += printk_address(addr); \
- } \
+#define HANDLE_STACK(cond) \
+ do while (cond) { \
+ unsigned long addr = *stack++; \
+ if (kernel_text_address(addr)) { \
+ printk(" "); \
+ printk_address(addr); \
+ } \
} while (0)

- for(i = 11; ; ) {
+ for( ; ; ) {
const char *id;
unsigned long *estack_end;
estack_end = in_exception_stack(cpu, (unsigned long)stack,
&used, &id);

if (estack_end) {
- i += printk(" <%s>", id);
+ printk(" <%s>", id);
HANDLE_STACK (stack < estack_end);
- i += printk(" <EOE>");
+ printk(" <EOE>");
stack = (unsigned long *) estack_end[-2];
continue;
}
@@ -231,11 +203,11 @@ void show_trace(unsigned long *stack)
(IRQSTACKSIZE - 64) / sizeof(*irqstack);

if (stack >= irqstack && stack < irqstack_end) {
- i += printk(" <IRQ>");
+ printk(" <IRQ>");
HANDLE_STACK (stack < irqstack_end);
stack = (unsigned long *) (irqstack_end[-1]);
irqstack_end = NULL;
- i += printk(" <EOI>");
+ printk(" <EOI>");
continue;
}
}
@@ -244,7 +216,6 @@ void show_trace(unsigned long *stack)

HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
#undef HANDLE_STACK
- printk("\n");
}

void show_stack(struct task_struct *tsk, unsigned long * rsp)
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 9bbd040..f668e64 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -20,7 +20,7 @@ const char *kallsyms_lookup(unsigned lon
char **modname, char *namebuf);

/* Replace "%s" in format with address, if found */
-extern void __print_symbol(const char *fmt, unsigned long address);
+extern int __print_symbol(const char *fmt, unsigned long address);

#else /* !CONFIG_KALLSYMS */

@@ -38,7 +38,10 @@ static inline const char *kallsyms_looku
}

/* Stupid that this does nothing, but I didn't create this mess. */
-#define __print_symbol(fmt, addr)
+static inline int __print_symbol(const char *fmt, unsigned long addr)
+{
+ return 0;
+}
#endif /*CONFIG_KALLSYMS*/

/* This macro allows us to keep printk typechecking */
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 39277dd..fbd7cb4 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -231,7 +231,7 @@ const char *kallsyms_lookup(unsigned lon
}

/* Replace "%s" in format with address, or returns -errno. */
-void __print_symbol(const char *fmt, unsigned long address)
+int __print_symbol(const char *fmt, unsigned long address)
{
char *modname;
const char *name;
@@ -251,7 +251,7 @@ void __print_symbol(const char *fmt, uns
else
sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
}
- printk(fmt, buffer);
+ return printk(fmt, buffer);
}

/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • Re: IE not starting
    ... You chopped the dump too soon. ... the Raw Stack Dump the words they display may be clues too. ... If you can get full symbols in your Stack Back Trace you would ...
    (microsoft.public.windows.inetexplorer.ie6.browser)
  • Re: Problem with code that inspects thread context and dumps stack trace
    ... It doesn't do a dump of all threads, ... "please dump your context" lock. ... You might also consider making the canonical order stack contain the thread ID of the ... >BOOL InitImagehlpFunctions(HANDLE hProcess, PSTR szPath) ...
    (microsoft.public.vc.mfc)
  • Re: Msimn.exe Has Generated Errors and Will Be Closed by Windows - Knowledge base no help!!!
    ... It's not just any Stack Back Trace you want to see. ... section in the dump below those interpreted instructions. ... >>> and message rules may have to be edited to point to correct mail folders and you will lose all subscribed newsgroups. ...
    (microsoft.public.windows.inetexplorer.ie6_outlookexpress)
  • Re: 4.8-p7 kernel panic (kld pcm related panic)
    ... flags not to use the `-z' flag, or try out my ugly hack. ... +fzopen(const char *fname, const char *mode) ... wb1 compressed core with fseek takes 1m22s ... With a virginal dump, using this and zlib takes ...
    (freebsd-stable)
  • Re: Getting proper Stack information from memory dump
    ... I just would like to confirm that in order to see detailed stack ... been built in "Debug" mode. ... when the app in production was built in "Release" mode. ... Open your dump in Windbg ...
    (microsoft.public.dotnet.framework.aspnet)