backtrace.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-06-02 Jesven the first version
  9. */
  10. #include <rtthread.h>
  11. #include <backtrace.h>
  12. #define BT_NESTING_MAX 100
  13. static int unwind_frame(struct bt_frame *frame)
  14. {
  15. unsigned long fp = frame->fp;
  16. if ((fp & 0x7)
  17. #ifdef RT_USING_LWP
  18. || fp < KERNEL_VADDR_START
  19. #endif
  20. )
  21. {
  22. return 1;
  23. }
  24. frame->fp = *(unsigned long *)fp;
  25. frame->pc = *(unsigned long *)(fp + 8);
  26. return 0;
  27. }
  28. static void walk_unwind(unsigned long pc, unsigned long fp)
  29. {
  30. struct bt_frame frame;
  31. unsigned long lr = pc;
  32. int nesting = 0;
  33. frame.fp = fp;
  34. while (nesting < BT_NESTING_MAX)
  35. {
  36. rt_kprintf(" %p", (void *)lr);
  37. if (unwind_frame(&frame))
  38. {
  39. break;
  40. }
  41. lr = frame.pc;
  42. nesting++;
  43. }
  44. }
  45. void backtrace(unsigned long pc, unsigned long lr, unsigned long fp)
  46. {
  47. rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc);
  48. walk_unwind(lr, fp);
  49. rt_kprintf("\n");
  50. }