diff options
author | Masao Uebayashi <uebayasi@cvs.openbsd.org> | 2015-02-08 05:36:52 +0000 |
---|---|---|
committer | Masao Uebayashi <uebayasi@cvs.openbsd.org> | 2015-02-08 05:36:52 +0000 |
commit | 2bd27b3e4b6685204cd7d1f2ab2569deb25f92dc (patch) | |
tree | d1f61467354d5d882bc23fa8891051c5f63c7c7c | |
parent | c124cda35b5f6510c01cdad6d0a1543f3cf5e36e (diff) |
Fix stack trace of tail calls. From NetBSD. OK miod@
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c index 9d3bd6ecb94..86cdf78242d 100644 --- a/sys/arch/mips64/mips64/trap.c +++ b/sys/arch/mips64/mips64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.103 2015/02/08 00:34:45 uebayasi Exp $ */ +/* $OpenBSD: trap.c,v 1.104 2015/02/08 05:36:51 uebayasi Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -1165,7 +1165,7 @@ void stacktrace_subr(struct trap_frame *, int, int (*)(const char*, ...)); * Print a stack backtrace. */ void -stacktrace(regs) +stacktrace(struct trap_frame *regs) struct trap_frame *regs; { stacktrace_subr(regs, 6, printf); @@ -1240,9 +1240,20 @@ loop: * Watch out for function tail optimizations. */ sym = db_search_symbol(pc, DB_STGY_ANY, &diff); - db_symbol_values(sym, &symname, 0); - if (sym != DB_SYM_NULL) + if (sym != DB_SYM_NULL && diff == 0) { + instr = kdbpeek(pc - 2 * sizeof(int)); + i.word = instr; + if (i.JType.op == OP_JAL) { + sym = db_search_symbol(pc - sizeof(int), + DB_STGY_ANY, &diff); + if (sym != DB_SYM_NULL && diff != 0) + diff += sizeof(int); + } + } + if (sym != DB_SYM_NULL) { + db_symbol_values(sym, &symname, 0); subr = pc - (vaddr_t)diff; + } #endif /* |