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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c
          +++ new/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c
↓ open down ↓ 189 lines elided ↑ open up ↑
 190  190  
 191  191  int
 192  192  mdb_ia32_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
 193  193      mdb_tgt_stack_f *func, void *arg)
 194  194  {
 195  195          mdb_tgt_gregset_t gregs;
 196  196          kreg_t *kregs = &gregs.kregs[0];
 197  197          int got_pc = (gsp->kregs[KREG_EIP] != 0);
 198  198          int err;
 199  199  
 200      -        struct {
      200 +        struct fr {
 201  201                  uintptr_t fr_savfp;
 202  202                  uintptr_t fr_savpc;
 203  203                  long fr_argv[32];
 204  204          } fr;
 205  205  
 206  206          uintptr_t fp = gsp->kregs[KREG_EBP];
 207  207          uintptr_t pc = gsp->kregs[KREG_EIP];
 208  208          uintptr_t lastfp = 0;
 209  209  
 210  210          ssize_t size;
 211  211          uint_t argc;
 212  212          int detect_exception_frames = 0;
      213 +        int advance_tortoise = 1;
      214 +        uintptr_t tortoise_fp = 0;
 213  215  #ifndef _KMDB
 214  216          int xp;
 215  217  
 216  218          if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0))
 217  219                  detect_exception_frames = 1;
 218  220  #endif
 219  221  
 220  222          bcopy(gsp, &gregs, sizeof (gregs));
 221  223  
 222  224          while (fp != 0) {
 223      -
 224      -                /*
 225      -                 * Ensure progress (increasing fp), and prevent
 226      -                 * endless loop with the same FP.
 227      -                 */
 228      -                if (fp <= lastfp) {
 229      -                        err = EMDB_STKFRAME;
 230      -                        goto badfp;
 231      -                }
 232  225                  if (fp & (STACK_ALIGN - 1)) {
 233  226                          err = EMDB_STKALIGN;
 234  227                          goto badfp;
 235  228                  }
 236  229                  if ((size = mdb_tgt_vread(t, &fr, sizeof (fr), fp)) >=
 237  230                      (ssize_t)(2 * sizeof (uintptr_t))) {
 238  231                          size -= (ssize_t)(2 * sizeof (uintptr_t));
 239  232                          argc = kvm_argcount(t, fr.fr_savpc, size);
 240  233                  } else {
 241  234                          err = EMDB_NOMAP;
 242  235                          goto badfp;
 243  236                  }
 244  237  
      238 +                if (tortoise_fp == 0) {
      239 +                        tortoise_fp = fp;
      240 +                } else {
      241 +                        if (advance_tortoise != 0) {
      242 +                                struct fr tfr;
      243 +
      244 +                                if (mdb_tgt_vread(t, &tfr, sizeof (tfr),
      245 +                                    tortoise_fp) != sizeof (tfr)) {
      246 +                                        err = EMDB_NOMAP;
      247 +                                        goto badfp;
      248 +                                }
      249 +
      250 +                                tortoise_fp = tfr.fr_savfp;
      251 +                        }
      252 +
      253 +                        if (fp == tortoise_fp) {
      254 +                                err = EMDB_STKFRAME;
      255 +                                goto badfp;
      256 +                        }
      257 +                }
      258 +
      259 +                advance_tortoise = !advance_tortoise;
      260 +
 245  261                  if (got_pc && func(arg, pc, argc, fr.fr_argv, &gregs) != 0)
 246  262                          break;
 247  263  
 248  264                  kregs[KREG_ESP] = kregs[KREG_EBP];
 249  265  
 250  266                  lastfp = fp;
 251  267                  fp = fr.fr_savfp;
 252  268                  /*
 253  269                   * The Xen hypervisor marks a stack frame as belonging to
 254  270                   * an exception by inverting the bits of the pointer to
↓ open down ↓ 167 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX