summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAruna Balakrishnaiah <aruna@linux.vnet.ibm.com>2014-08-13 14:01:19 +0530
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-13 18:42:25 +1000
commit5b23b0c698e475042abb0b617521b22004b1461d (patch)
tree1105313429d5b950dec555e5c0018682cdf7c012 /core
parentbfd7bdcb3b9ded18a1f9ce20a274c3198ab93c63 (diff)
downloadblackbird-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.c30
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);
+}
OpenPOWER on IntegriCloud