diff options
author | 2019-10-15 10:13:03 +0000 | |
---|---|---|
committer | 2019-10-15 10:13:03 +0000 | |
commit | 19120e8f37ae8c3d69ee4ec889299229b3996b4d (patch) | |
tree | 3d6a1c11e6eaf477319db3486fb6ea0cdbda7e19 /sys | |
parent | Reduce the number of places where `p_priority' and `p_stat' are set. (diff) | |
download | wireguard-openbsd-19120e8f37ae8c3d69ee4ec889299229b3996b4d.tar.xz wireguard-openbsd-19120e8f37ae8c3d69ee4ec889299229b3996b4d.zip |
Fix db_stack_dump() w/ custom addr & implement db_save_stack_trace().
Substract the BIAS from the `addr' argument since the unwinding
algorithm assumes the given frame address doesn't include it.
In other words, account for the BIAS added by __builtin_frame_address().
Inputs from and ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/sparc64/db_trace.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/arch/sparc64/sparc64/db_trace.c b/sys/arch/sparc64/sparc64/db_trace.c index 03cab11e46b..4fe8ef619a1 100644 --- a/sys/arch/sparc64/sparc64/db_trace.c +++ b/sys/arch/sparc64/sparc64/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.14 2017/11/03 11:29:47 jasper Exp $ */ +/* $OpenBSD: db_trace.c,v 1.15 2019/10/15 10:13:03 mpi Exp $ */ /* $NetBSD: db_trace.c,v 1.23 2001/07/10 06:06:16 eeh Exp $ */ /* @@ -87,7 +87,7 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, frame = (vaddr_t)u->u_pcb.pcb_sp; (*pr)("at %p\n", frame); } else { - frame = (vaddr_t)addr; + frame = (vaddr_t)addr - BIAS; } } @@ -151,6 +151,33 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, } } +void +db_save_stack_trace(struct db_stack_trace *st) +{ + struct frame64 *f64; + db_addr_t pc; + vaddr_t frame; + + frame = (vaddr_t)__builtin_frame_address(0) - BIAS; + if ((frame & 1) == 0) + return; + + st->st_count = 0; + while (st->st_count < DB_STACK_TRACE_MAX) { + f64 = (struct frame64 *)(frame + BIAS); + pc = (db_addr_t)KLOAD(f64->fr_pc); + + st->st_pc[st->st_count++] = pc; + frame = KLOAD(f64->fr_fp); + + if (pc < KERNBASE || pc >= KERNEND) + break; + if (frame < KERNBASE) + break; + if ((frame & 1) == 0) + break; + } +} void db_dump_window(db_expr_t addr, int have_addr, db_expr_t count, char *modif) |