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

*** 195,205 **** mdb_tgt_gregset_t gregs; kreg_t *kregs = &gregs.kregs[0]; int got_pc = (gsp->kregs[KREG_EIP] != 0); int err; ! struct { uintptr_t fr_savfp; uintptr_t fr_savpc; long fr_argv[32]; } fr; --- 195,205 ---- mdb_tgt_gregset_t gregs; kreg_t *kregs = &gregs.kregs[0]; int got_pc = (gsp->kregs[KREG_EIP] != 0); int err; ! struct fr { uintptr_t fr_savfp; uintptr_t fr_savpc; long fr_argv[32]; } fr;
*** 208,236 **** uintptr_t lastfp = 0; ssize_t size; uint_t argc; int detect_exception_frames = 0; #ifndef _KMDB int xp; if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0)) detect_exception_frames = 1; #endif bcopy(gsp, &gregs, sizeof (gregs)); while (fp != 0) { - - /* - * Ensure progress (increasing fp), and prevent - * endless loop with the same FP. - */ - if (fp <= lastfp) { - err = EMDB_STKFRAME; - goto badfp; - } if (fp & (STACK_ALIGN - 1)) { err = EMDB_STKALIGN; goto badfp; } if ((size = mdb_tgt_vread(t, &fr, sizeof (fr), fp)) >= --- 208,229 ---- uintptr_t lastfp = 0; ssize_t size; uint_t argc; int detect_exception_frames = 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)) detect_exception_frames = 1; #endif bcopy(gsp, &gregs, sizeof (gregs)); while (fp != 0) { if (fp & (STACK_ALIGN - 1)) { err = EMDB_STKALIGN; goto badfp; } if ((size = mdb_tgt_vread(t, &fr, sizeof (fr), fp)) >=
*** 240,249 **** --- 233,265 ---- } else { 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 (got_pc && func(arg, pc, argc, fr.fr_argv, &gregs) != 0) break; kregs[KREG_ESP] = kregs[KREG_EBP];