Print this page
5554 kmdb can't trace stacks that begin within itself
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>

*** 206,216 **** long fr_argv[32]; int start_index; /* index to save_instr where to start comparison */ int err; int i; ! struct { uintptr_t fr_savfp; uintptr_t fr_savpc; } fr; uintptr_t fp = gsp->kregs[KREG_RBP]; --- 206,216 ---- long fr_argv[32]; int start_index; /* index to save_instr where to start comparison */ int err; int i; ! struct fr { uintptr_t fr_savfp; uintptr_t fr_savpc; } fr; uintptr_t fp = gsp->kregs[KREG_RBP];
*** 223,232 **** --- 223,234 ---- GElf_Sym s; mdb_syminfo_t sip; mdb_ctf_funcinfo_t mfp; int xpv_panic = 0; + int advance_tortoise = 1; + uintptr_t tortoise_fp = 0; #ifndef _KMDB int xp; if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0)) xpv_panic = 1;
*** 235,257 **** bcopy(gsp, &gregs, sizeof (gregs)); while (fp != 0) { int args_style = 0; ! /* ! * Ensure progress (increasing fp), and prevent ! * endless loop with the same FP. ! */ ! if (fp <= lastfp) { ! err = EMDB_STKFRAME; goto badfp; } ! if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) { err = EMDB_NOMAP; goto badfp; } if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0, &s, &sip) == 0) && (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) { int return_type = mdb_ctf_type_kind(mfp.mtf_return); mdb_ctf_id_t args_types[5]; --- 237,274 ---- bcopy(gsp, &gregs, sizeof (gregs)); while (fp != 0) { int args_style = 0; ! if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) { ! err = EMDB_NOMAP; goto badfp; } ! ! if (tortoise_fp == 0) { ! tortoise_fp = fp; ! } else { ! if (advance_tortoise != 0) { ! struct fr tfr; ! ! if (mdb_tgt_vread(t, &tfr, sizeof (tfr), ! tortoise_fp) != sizeof (tfr)) { err = EMDB_NOMAP; goto badfp; } + tortoise_fp = tfr.fr_savfp; + } + + if (fp == tortoise_fp) { + err = EMDB_STKFRAME; + goto badfp; + } + } + + advance_tortoise = !advance_tortoise; + if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0, &s, &sip) == 0) && (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) { int return_type = mdb_ctf_type_kind(mfp.mtf_return); mdb_ctf_id_t args_types[5];