123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "apic.h"
- #include "io.h"
- #include "amd64.h"
- int backtrace_list(uintptr_t pc, uintptr_t fp, uintptr_t *pcs, size_t nr_slots)
- {
- size_t nr_pcs = 0;
- while (fp && nr_pcs < nr_slots) {
- /* could put some sanity checks in here... */
- pcs[nr_pcs++] = pc;
- //iprint("PC %p FP %p\n", pc, fp);
- if (fp < KTZERO)
- break;
- /* PC becomes the retaddr - 1. the -1 is to put our PC back inside the
- * function that called us. this was necessary in case we called as the
- * last instruction in a function (would have to never return). not
- * sure how necessary this still is. */
- pc = *(uintptr_t*)(fp + sizeof(uintptr_t)) - 1;
- fp = *(uintptr_t*)fp;
- }
- return nr_pcs;
- }
- #if 0
- void backtrace_frame(uintptr_t eip, uintptr_t ebp)
- {
- char *func_name;
- #define MAX_BT_DEPTH 20
- uintptr_t pcs[MAX_BT_DEPTH];
- size_t nr_pcs = backtrace_list(eip, ebp, pcs, MAX_BT_DEPTH);
- for (int i = 0; i < nr_pcs; i++) {
- func_name = get_fn_name(pcs[i]);
- print("#%02d [<%p>] in %s\n", i + 1, pcs[i], func_name);
- kfree(func_name);
- }
- }
- void backtrace(void)
- {
- uintptr_t ebp, eip;
- ebp = read_bp();
- /* retaddr is right above ebp on the stack. we subtract an additional 1 to
- * make sure the eip we get is actually in the function that called us.
- * i had a couple cases early on where call was the last instruction in a
- * function, and simply reading the retaddr would point into another
- * function (the next one in the object) */
- eip = *(uintptr_t*)(ebp + sizeof(uintptr_t)) - 1;
- /* jump back a frame (out of backtrace) */
- ebp = *(uintptr_t*)ebp;
- printk("Stack Backtrace on Core %d:\n", core_id());
- backtrace_frame(eip, ebp);
- }
- #endif
|