backtrace.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "apic.h"
  7. #include "io.h"
  8. #include "amd64.h"
  9. int backtrace_list(uintptr_t pc, uintptr_t fp, uintptr_t *pcs, size_t nr_slots)
  10. {
  11. size_t nr_pcs = 0;
  12. while (fp && nr_pcs < nr_slots) {
  13. /* could put some sanity checks in here... */
  14. pcs[nr_pcs++] = pc;
  15. //iprint("PC %p FP %p\n", pc, fp);
  16. if (fp < KTZERO)
  17. break;
  18. /* PC becomes the retaddr - 1. the -1 is to put our PC back inside the
  19. * function that called us. this was necessary in case we called as the
  20. * last instruction in a function (would have to never return). not
  21. * sure how necessary this still is. */
  22. pc = *(uintptr_t*)(fp + sizeof(uintptr_t)) - 1;
  23. fp = *(uintptr_t*)fp;
  24. }
  25. return nr_pcs;
  26. }
  27. #if 0
  28. void backtrace_frame(uintptr_t eip, uintptr_t ebp)
  29. {
  30. char *func_name;
  31. #define MAX_BT_DEPTH 20
  32. uintptr_t pcs[MAX_BT_DEPTH];
  33. size_t nr_pcs = backtrace_list(eip, ebp, pcs, MAX_BT_DEPTH);
  34. for (int i = 0; i < nr_pcs; i++) {
  35. func_name = get_fn_name(pcs[i]);
  36. print("#%02d [<%p>] in %s\n", i + 1, pcs[i], func_name);
  37. kfree(func_name);
  38. }
  39. }
  40. void backtrace(void)
  41. {
  42. uintptr_t ebp, eip;
  43. ebp = read_bp();
  44. /* retaddr is right above ebp on the stack. we subtract an additional 1 to
  45. * make sure the eip we get is actually in the function that called us.
  46. * i had a couple cases early on where call was the last instruction in a
  47. * function, and simply reading the retaddr would point into another
  48. * function (the next one in the object) */
  49. eip = *(uintptr_t*)(ebp + sizeof(uintptr_t)) - 1;
  50. /* jump back a frame (out of backtrace) */
  51. ebp = *(uintptr_t*)ebp;
  52. printk("Stack Backtrace on Core %d:\n", core_id());
  53. backtrace_frame(eip, ebp);
  54. }
  55. #endif