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];