jesven 3 лет назад
Родитель
Сommit
059c34c90b
3 измененных файлов с 82 добавлено и 0 удалено
  1. 57 0
      libcpu/aarch64/common/backtrace.c
  2. 22 0
      libcpu/aarch64/common/backtrace.h
  3. 3 0
      libcpu/aarch64/common/trap.c

+ 57 - 0
libcpu/aarch64/common/backtrace.c

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-06-02     Jesven       the first version
+ */
+
+#include <rtthread.h>
+#include <backtrace.h>
+
+#define BT_NESTING_MAX 100
+
+static int unwind_frame(struct bt_frame *frame)
+{
+    unsigned long fp = frame->fp;
+
+    if ((fp & 0x7)
+#ifdef RT_USING_LWP
+         || fp < KERNEL_VADDR_START
+#endif
+            )
+    {
+        return 1;
+    }
+    frame->fp = *(unsigned long *)fp;
+    frame->pc = *(unsigned long *)(fp + 8);
+    return 0;
+}
+
+static void walk_unwind(unsigned long pc, unsigned long fp)
+{
+    struct bt_frame frame;
+    unsigned long lr = pc;
+    int nesting = 0;
+
+    frame.fp = fp;
+    while (nesting < BT_NESTING_MAX)
+    {
+        rt_kprintf(" %p", (void *)lr);
+        if (unwind_frame(&frame))
+        {
+            break;
+        }
+        lr = frame.pc;
+        nesting++;
+    }
+}
+
+void backtrace(unsigned long pc, unsigned long lr, unsigned long fp)
+{
+    rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc);
+    walk_unwind(lr, fp);
+    rt_kprintf("\n");
+}

+ 22 - 0
libcpu/aarch64/common/backtrace.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-06-02     Jesven       the first version
+ */
+
+#ifndef  __BACKTRACE_H__
+#define  __BACKTRACE_H__
+
+struct bt_frame
+{
+    unsigned long fp;
+    unsigned long pc;
+};
+
+void backtrace(unsigned long pc, unsigned long lr, unsigned long fp);
+
+#endif  /*__BACKTRACE_H__*/

+ 3 - 0
libcpu/aarch64/common/trap.c

@@ -15,6 +15,8 @@
 #include <armv8.h>
 #include "interrupt.h"
 
+#include <backtrace.h>
+
 void rt_unwind(struct rt_hw_exp_stack *regs, int pc_adj)
 {
 }
@@ -251,6 +253,7 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs)
 #ifdef RT_USING_FINSH
     list_thread();
 #endif
+    backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29);
     rt_hw_cpu_shutdown();
 }