diff options
author | Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com> | 2014-08-13 14:01:19 +0530 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-13 18:42:25 +1000 |
commit | 5b23b0c698e475042abb0b617521b22004b1461d (patch) | |
tree | 1105313429d5b950dec555e5c0018682cdf7c012 /core | |
parent | bfd7bdcb3b9ded18a1f9ce20a274c3198ab93c63 (diff) | |
download | blackbird-skiboot-5b23b0c698e475042abb0b617521b22004b1461d.tar.gz blackbird-skiboot-5b23b0c698e475042abb0b617521b22004b1461d.zip |
attn: Dump backtrace to buffer
Existing backtrace will dump the backtrace to stderr.
__backtrace will dump the backtrace to buffer. backtrace()
will call __backtrace internally and dump it to stderr.
Signed-off-by Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/backtrace.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/core/backtrace.c b/core/backtrace.c index 47b771f2..71c5d11f 100644 --- a/core/backtrace.c +++ b/core/backtrace.c @@ -19,11 +19,17 @@ #include <processor.h> #include <cpu.h> -void backtrace(void) +/* Upto 10 frames each of length 40 bytes + header = 430 bytes */ +#define STACK_BUF_SZ 440 + +/* Dumps backtrace to buffer */ +void __backtrace(char *bt_buf, int bt_buf_len) { unsigned int pir = mfspr(SPR_PIR); unsigned long *sp; unsigned long *bottom, *top; + char *buf; + int len = 0; /* Check if there's a __builtin_something instead */ asm("mr %0,1" : "=r" (sp)); @@ -31,11 +37,25 @@ void backtrace(void) bottom = cpu_stack_bottom(pir); top = cpu_stack_top(pir); + if (!bt_buf || !bt_buf_len) + return; + + buf = bt_buf; + len += snprintf(buf, bt_buf_len, "CPU %08x Backtrace:\n", pir); /* XXX Handle SMP */ - fprintf(stderr, "CPU %08x Backtrace:\n", pir); - while(sp > bottom && sp < top) { - prlog(PR_EMERG, " S: %016lx R: %016lx\n", - (unsigned long)sp, sp[2]); + while (sp > bottom && sp < top) { + len += snprintf(buf + len, bt_buf_len - len, " S: %016lx " + "R: %016lx\n", (unsigned long)sp, sp[2]); sp = (unsigned long *)sp[0]; } } + +void backtrace(void) +{ + char bt_buf[STACK_BUF_SZ]; + + memset(bt_buf, 0, STACK_BUF_SZ); + __backtrace(bt_buf, STACK_BUF_SZ); + + fputs(bt_buf, stderr); +} |