1 /*
   2  * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "util.h"
  27 #include "stepControl.h"
  28 #include "eventHandler.h"
  29 #include "eventHelper.h"
  30 #include "threadControl.h"
  31 #include "SDE.h"
  32 
  33 static jrawMonitorID stepLock;
  34 
  35 /*
  36  * Most enabling/disabling of JVMTI events happens implicitly through
  37  * the inserting and freeing of handlers for those events. Stepping is
  38  * different because requested steps are usually not identical to JVMTI steps.
  39  * They usually require multiple events step, and otherwise, before they
  40  * complete. While a step request is pending, we may need to temporarily
  41  * disable and re-enable stepping, but we can't just remove the handlers
  42  * because that would break the application's ability to remove the
  43  * events. So, for step events only, we directly enable and disable stepping.
  44  * This is safe because there can only ever be one pending step request
  45  * per thread.
  46  */
  47 static void
  48 enableStepping(jthread thread)
  49 {
  50     jvmtiError error;
  51 
  52     LOG_STEP(("enableStepping: thread=%p", thread));
  53 
  54     error = threadControl_setEventMode(JVMTI_ENABLE, EI_SINGLE_STEP,
  55                                             thread);
  56     if (error != JVMTI_ERROR_NONE) {
  57         EXIT_ERROR(error, "enabling single step");
  58     }
  59 }
  60 
  61 static void
  62 disableStepping(jthread thread)
  63 {
  64     jvmtiError error;
  65 
  66     LOG_STEP(("disableStepping: thread=%p", thread));
  67 
  68     error = threadControl_setEventMode(JVMTI_DISABLE, EI_SINGLE_STEP,
  69                                             thread);
  70     if (error != JVMTI_ERROR_NONE) {
  71         EXIT_ERROR(error, "disabling single step");
  72     }
  73 }
  74 
  75 void stepControl_enableStepping(jthread thread) {
  76   enableStepping(thread);
  77 }
  78 
  79 void stepControl_disableStepping(jthread thread) {
  80   disableStepping(thread);
  81 }
  82 
  83 static jvmtiError
  84 getFrameLocation(jthread thread,
  85         jclass *pclazz, jmethodID *pmethod, jlocation *plocation)
  86 {
  87     jvmtiError error;
  88 
  89     *pclazz = NULL;
  90     *pmethod = NULL;
  91     *plocation = -1;
  92 
  93     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
  94             (gdata->jvmti, thread, 0, pmethod, plocation);
  95     if (error == JVMTI_ERROR_NONE && *pmethod!=NULL ) {
  96         /* This also serves to verify that the methodID is valid */
  97         error = methodClass(*pmethod, pclazz);
  98     }
  99     return error;
 100 }
 101 
 102 static void
 103 getLineNumberTable(jmethodID method, jint *pcount,
 104                 jvmtiLineNumberEntry **ptable)
 105 {
 106     jvmtiError error;
 107 
 108     *pcount = 0;
 109     *ptable = NULL;
 110 
 111     /* If the method is native or obsolete, don't even ask for the line table */
 112     if ( isMethodObsolete(method) || isMethodNative(method)) {
 113         return;
 114     }
 115 
 116     error = JVMTI_FUNC_PTR(gdata->jvmti,GetLineNumberTable)
 117                 (gdata->jvmti, method, pcount, ptable);
 118     if (error != JVMTI_ERROR_NONE) {
 119         *pcount = 0;
 120     }
 121 }
 122 
 123 static jint
 124 findLineNumber(jthread thread, jlocation location,
 125                jvmtiLineNumberEntry *lines, jint count)
 126 {
 127     jint line = -1;
 128 
 129     if (location != -1) {
 130         if (count > 0) {
 131             jint i;
 132             /* any preface before first line is assigned to first line */
 133             for (i=1; i<count; i++) {
 134                 if (location < lines[i].start_location) {
 135                     break;
 136                 }
 137             }
 138             line = lines[i-1].line_number;
 139         }
 140     }
 141     return line;
 142 }
 143 
 144 static jboolean
 145 hasLineNumbers(jmethodID method)
 146 {
 147     jint count;
 148     jvmtiLineNumberEntry *table;
 149 
 150     getLineNumberTable(method, &count, &table);
 151     if ( count == 0 ) {
 152         return JNI_FALSE;
 153     } else {
 154         jvmtiDeallocate(table);
 155     }
 156     return JNI_TRUE;
 157 }
 158 
 159 static jvmtiError
 160 initState(JNIEnv *env, jthread thread, StepRequest *step)
 161 {
 162     jvmtiError error;
 163 
 164     /*
 165      * Initial values that may be changed below
 166      */
 167     step->fromLine = -1;
 168     step->fromNative = JNI_FALSE;
 169     step->frameExited = JNI_FALSE;
 170     step->fromStackDepth = getThreadFrameCount(thread);
 171 
 172     if (step->fromStackDepth <= 0) {
 173         /*
 174          * If there are no stack frames, treat the step as though
 175          * from a native frame. This is most likely to occur at the
 176          * beginning of a debug session, right after the VM_INIT event,
 177          * so we need to do something intelligent.
 178          */
 179         step->fromNative = JNI_TRUE;
 180         return JVMTI_ERROR_NONE;
 181     }
 182 
 183     /*
 184      * Try to get a notification on frame pop. If we're in an opaque frame
 185      * we won't be able to, but we can use other methods to detect that
 186      * a native frame has exited.
 187      *
 188      * TO DO: explain the need for this notification.
 189      */
 190     error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)
 191                 (gdata->jvmti, thread, 0);
 192     if (error == JVMTI_ERROR_OPAQUE_FRAME) {
 193         step->fromNative = JNI_TRUE;
 194         error = JVMTI_ERROR_NONE;
 195         /* continue without error */
 196     } else if (error == JVMTI_ERROR_DUPLICATE) {
 197         error = JVMTI_ERROR_NONE;
 198         /* Already being notified, continue without error */
 199     } else if (error != JVMTI_ERROR_NONE) {
 200         return error;
 201     }
 202 
 203     LOG_STEP(("initState(): frame=%d", step->fromStackDepth));
 204 
 205     /*
 206      * Note: we can't undo the frame pop notify, so
 207      * we'll just have to let the handler ignore it if
 208      * there are any errors below.
 209      */
 210 
 211     if (step->granularity == JDWP_STEP_SIZE(LINE) ) {
 212 
 213         LOG_STEP(("initState(): Begin line step"));
 214 
 215         WITH_LOCAL_REFS(env, 1) {
 216 
 217             jclass clazz;
 218             jmethodID method;
 219             jlocation location;
 220 
 221             error = getFrameLocation(thread, &clazz, &method, &location);
 222             if (error == JVMTI_ERROR_NONE) {
 223                 /* Clear out previous line table only if we changed methods */
 224                 if ( method != step->method ) {
 225                     step->lineEntryCount = 0;
 226                     if (step->lineEntries != NULL) {
 227                         jvmtiDeallocate(step->lineEntries);
 228                         step->lineEntries = NULL;
 229                     }
 230                     step->method = method;
 231                     getLineNumberTable(step->method,
 232                                  &step->lineEntryCount, &step->lineEntries);
 233                     if (step->lineEntryCount > 0) {
 234                         convertLineNumberTable(env, clazz,
 235                                 &step->lineEntryCount, &step->lineEntries);
 236                     }
 237                 }
 238                 step->fromLine = findLineNumber(thread, location,
 239                                      step->lineEntries, step->lineEntryCount);
 240             }
 241 
 242         } END_WITH_LOCAL_REFS(env);
 243 
 244     }
 245 
 246     return error;
 247 }
 248 
 249 /*
 250  * TO DO: The step handlers (handleFrameChange and handleStep can
 251  * be broken down and made simpler now that we can install and de-install event
 252  * handlers.
 253  */
 254 static void
 255 handleFramePopEvent(JNIEnv *env, EventInfo *evinfo,
 256                     HandlerNode *node,
 257                     struct bag *eventBag)
 258 {
 259     StepRequest *step;
 260     jthread thread = evinfo->thread;
 261 
 262     stepControl_lock();
 263 
 264     step = threadControl_getStepRequest(thread);
 265     if (step == NULL) {
 266         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step request");
 267     }
 268 
 269     if (step->pending) {
 270         /*
 271          * Note: current depth is reported as *before* the pending frame
 272          * pop.
 273          */
 274         jint currentDepth;
 275         jint fromDepth;
 276         jint afterPopDepth;
 277 
 278         currentDepth = getThreadFrameCount(thread);
 279         fromDepth = step->fromStackDepth;
 280         afterPopDepth = currentDepth-1;
 281 
 282         LOG_STEP(("handleFramePopEvent: BEGIN fromDepth=%d, currentDepth=%d",
 283                         fromDepth, currentDepth));
 284 
 285         /*
 286          * If we are exiting the original stepping frame, record that
 287          * fact here. Once the next step event comes in, we can safely
 288          * stop stepping there.
 289          */
 290         if (fromDepth > afterPopDepth ) {
 291             step->frameExited = JNI_TRUE;
 292         }
 293 
 294         if (step->depth == JDWP_STEP_DEPTH(OVER)) {
 295             /*
 296              * Either
 297              * 1) the original stepping frame is about to be popped
 298              *    [fromDepth == currentDepth]. Re-enable stepping to
 299              *    reach a point where we can stop.
 300              * 2) a method called from the stepping frame has returned
 301              *    (during which we had stepping disabled)
 302              *    [fromDepth == currentDepth - 1]. Re-enable stepping
 303              *    so that we can continue instructions steps in the
 304              *    original stepping frame.
 305              * 3) a method further down the call chain has notified
 306              *    of a frame pop [fromDepth < currentDepth - 1]. This
 307              *    *might* represent case (2) above if the stepping frame
 308              *    was calling a native method which in turn called a
 309              *    java method. If so, we must enable stepping to
 310              *    ensure that we get control back after the intervening
 311              *    native frame is popped (you can't get frame pop
 312              *    notifications on native frames). If the native caller
 313              *    calls another Java method before returning,
 314              *    stepping will be diabled again and another frame pop
 315              *    will be awaited.
 316              *
 317              *    If it turns out that this is not case (2) with native
 318              *    methods, then the enabled stepping is benign and
 319              *    will be disabled again on the next step event.
 320              *
 321              * Note that the condition not covered above,
 322              * [fromDepth > currentDepth] shouldn't happen since it means
 323              * that too many frames have been popped. For robustness,
 324              * we enable stepping in that case too, so that the errant
 325              * step-over can be stopped.
 326              *
 327              */
 328             LOG_STEP(("handleFramePopEvent: starting singlestep, depth==OVER"));
 329             enableStepping(thread);
 330         } else if (step->depth == JDWP_STEP_DEPTH(OUT) &&
 331                    fromDepth > afterPopDepth) {
 332             /*
 333              * The original stepping frame is about to be popped. Step
 334              * until we reach the next safe place to stop.
 335              */
 336             LOG_STEP(("handleFramePopEvent: starting singlestep, depth==OUT && fromDepth > afterPopDepth (%d>%d)",fromDepth, afterPopDepth));
 337             enableStepping(thread);
 338         } else if (step->methodEnterHandlerNode != NULL) {
 339             /* We installed a method entry event handler as part of a step into operation. */
 340             JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO));
 341             if (fromDepth >= afterPopDepth) {
 342                 /*
 343                  * We've popped back to the original stepping frame without finding a place to stop.
 344                  * Resume stepping in the original frame.
 345                  */
 346                 LOG_STEP(("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth >= afterPopDepth (%d>=%d)", fromDepth, afterPopDepth));
 347             } else {
 348                 /*
 349                  * The only way this should happen is if FramePop events were enabled to support a
 350                  * CONTINUATION_RUN event while doing a STEP_INTO. See stepControl_handleContinuationRun().
 351                  * Resume stepping in the current frame. If it is not the correct frame to resume stepping
 352                  * in, then handleStep() will disable single stepping and setup another FramePop request.
 353                  */
 354                 LOG_STEP(("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth < afterPopDepth (%d<%d)", fromDepth, afterPopDepth));
 355             }
 356             enableStepping(thread);
 357             (void)eventHandler_free(step->methodEnterHandlerNode);
 358             step->methodEnterHandlerNode = NULL;
 359         }
 360         LOG_STEP(("handleFramePopEvent: finished"));
 361     }
 362 
 363     stepControl_unlock();
 364 }
 365 
 366 static void
 367 handleExceptionCatchEvent(JNIEnv *env, EventInfo *evinfo,
 368                           HandlerNode *node,
 369                           struct bag *eventBag)
 370 {
 371     StepRequest *step;
 372     jthread thread = evinfo->thread;
 373 
 374     stepControl_lock();
 375 
 376     step = threadControl_getStepRequest(thread);
 377     if (step == NULL) {
 378         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step request");
 379     }
 380 
 381     if (step->pending) {
 382         /*
 383          *  Determine where we are on the call stack relative to where
 384          *  we started.
 385          */
 386         jint currentDepth = getThreadFrameCount(thread);
 387         jint fromDepth = step->fromStackDepth;
 388 
 389         LOG_STEP(("handleExceptionCatchEvent: fromDepth=%d, currentDepth=%d",
 390                         fromDepth, currentDepth));
 391 
 392         /*
 393          * If we are exiting the original stepping frame, record that
 394          * fact here. Once the next step event comes in, we can safely
 395          * stop stepping there.
 396          */
 397         if (fromDepth > currentDepth) {
 398             step->frameExited = JNI_TRUE;
 399         }
 400 
 401         if (step->depth == JDWP_STEP_DEPTH(OVER) &&
 402             fromDepth >= currentDepth) {
 403             /*
 404              * Either the original stepping frame is done,
 405              * or a called method has returned (during which we had stepping
 406              * disabled). In either case we must resume stepping.
 407              */
 408             enableStepping(thread);
 409         } else if (step->depth == JDWP_STEP_DEPTH(OUT) &&
 410                    fromDepth > currentDepth) {
 411             /*
 412              * The original stepping frame is done. Step
 413              * until we reach the next safe place to stop.
 414              */
 415             enableStepping(thread);
 416         } else if (step->methodEnterHandlerNode != NULL &&
 417                    fromDepth >= currentDepth) {
 418             /*
 419              * We installed a method entry event handler as part of a
 420              * step into operation. We've popped back to the original
 421              * stepping frame or higher without finding a place to stop.
 422              * Resume stepping in the original frame.
 423              */
 424             enableStepping(thread);
 425             (void)eventHandler_free(step->methodEnterHandlerNode);
 426             step->methodEnterHandlerNode = NULL;
 427         }
 428     }
 429 
 430     stepControl_unlock();
 431 }
 432 
 433 /*
 434  * Help deal with a METHOD_ENTRY event (or a simulated one). Returns JNI_TRUE if
 435  * single stepping gets enabled.
 436  */
 437 static jboolean
 438 methodEnterHelper(JNIEnv *env, jthread thread, StepRequest *step, jclass clazz, jmethodID method)
 439 {
 440     jboolean steppingEnabled = JNI_FALSE;
 441     if (step->pending) {
 442         char *classname = getClassname(clazz);
 443 
 444         /* This handler is relevant only to step into. */
 445         JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO));
 446 
 447         if ((!eventFilter_predictFiltering(step->stepHandlerNode, clazz, classname))
 448             && (step->granularity != JDWP_STEP_SIZE(LINE) || hasLineNumbers(method))) {
 449             /*
 450              * We've found a suitable method in which to resume stepping.
 451              * We can also get rid of the method entry handler now.
 452              */
 453             enableStepping(thread);
 454             steppingEnabled = JNI_TRUE;
 455             if ( step->methodEnterHandlerNode != NULL ) {
 456                 (void)eventHandler_free(step->methodEnterHandlerNode);
 457                 step->methodEnterHandlerNode = NULL;
 458             }
 459         }
 460         jvmtiDeallocate(classname);
 461         classname = NULL;
 462     }
 463     return steppingEnabled;
 464 }
 465 
 466 static void
 467 handleMethodEnterEvent(JNIEnv *env, EventInfo *evinfo,
 468                        HandlerNode *node,
 469                        struct bag *eventBag)
 470 {
 471     StepRequest *step;
 472     jthread thread = evinfo->thread;
 473 
 474     stepControl_lock();
 475     LOG_STEP(("handleMethodEnterEvent: thread=%p", thread));
 476     step = threadControl_getStepRequest(thread);
 477     if (step == NULL) {
 478         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step request");
 479     }
 480     methodEnterHelper(env, thread, step, evinfo->clazz, evinfo->method);
 481     stepControl_unlock();
 482 }
 483 
 484 void
 485 stepControl_handleContinuationRun(JNIEnv *env, jthread thread, StepRequest *step)
 486 {
 487     stepControl_lock();
 488     if (step->methodEnterHandlerNode != NULL) {
 489         /* 
 490          * Looks like we were doing a single step INTO with filtering enabled, so a MethodEntry
 491          * handler was installed to detect when we enter an unfiltered method. It's possible
 492          * that the continuation method we are resuming execution in is unfiltered, but there
 493          * will be no MethodEntry event for it. So we fake one here so the single stepping
 494          * state is udpated appropriately.
 495          */
 496         jboolean steppingEnabled;
 497         jclass clazz;
 498         jmethodID method;
 499         jlocation location;
 500         jvmtiError error;
 501         
 502         JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO));
 503 
 504         /*
 505          * We leverage the existing MethodEntry handler support for this, but it needs to know
 506          * the location of the MethodEntry, so we get this from the current frame.
 507          */
 508         error = getFrameLocation(thread, &clazz, &method, &location);
 509         if (error != JVMTI_ERROR_NONE) {
 510             EXIT_ERROR(error, "getting frame location");
 511         }
 512         steppingEnabled = methodEnterHelper(env, thread, step, clazz, method);
 513 
 514         if (!steppingEnabled) {
 515             /*
 516              * It looks like the continuation is resuming in a filtered method. We need to setup
 517              * a FramePop request on the current frame, so when it exits we can check if the 
 518              * method we return to is filtered, and enable single stepping if not.
 519              */
 520             error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)
 521                 (gdata->jvmti, thread, 0);
 522             if (error == JVMTI_ERROR_DUPLICATE) {
 523                 error = JVMTI_ERROR_NONE;
 524             } else if (error != JVMTI_ERROR_NONE) {
 525                 EXIT_ERROR(error, "setting up notify frame pop");
 526             }
 527         }
 528     }
 529     stepControl_unlock();
 530 }
 531 
 532 static void
 533 completeStep(JNIEnv *env, jthread thread, StepRequest *step)
 534 {
 535     jvmtiError error;
 536 
 537     /*
 538      * We've completed a step; reset state for the next one, if any
 539      */
 540 
 541     LOG_STEP(("completeStep: thread=%p", thread));
 542 
 543     if (step->methodEnterHandlerNode != NULL) {
 544         (void)eventHandler_free(step->methodEnterHandlerNode);
 545         step->methodEnterHandlerNode = NULL;
 546     }
 547 
 548     error = initState(env, thread, step);
 549     if (error != JVMTI_ERROR_NONE) {
 550         /*
 551          * None of the initState errors should happen after one step
 552          * has successfully completed.
 553          */
 554         EXIT_ERROR(error, "initializing step state");
 555     }
 556 }
 557 
 558 jboolean
 559 stepControl_handleStep(JNIEnv *env, jthread thread, jthread fiber, jboolean matchesFiber,
 560                        jclass clazz, jmethodID method)
 561 {
 562     jboolean completed = JNI_FALSE;
 563     StepRequest *step;
 564     jint currentDepth;
 565     jint fromDepth;
 566     jvmtiError error;
 567     char *classname;
 568 
 569     classname = NULL;
 570     stepControl_lock();
 571 
 572     step = threadControl_getStepRequest(thread);
 573     if (step == NULL) {
 574         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step request");
 575     }
 576 
 577     /*
 578      * If no step is currently pending, ignore the event
 579      */
 580     if (!step->pending) {
 581         goto done;
 582     }
 583 
 584     LOG_STEP(("stepControl_handleStep: thread=%p", thread));
 585 
 586     /* Make sure the StepRequest is in agreement as to whether or not we are stepping in a fiber. */
 587     JDI_ASSERT(step->is_fiber == matchesFiber);
 588 
 589     /*
 590      * We never filter step into instruction. It's always over on the
 591      * first step event.
 592      */
 593     if (step->depth == JDWP_STEP_DEPTH(INTO) &&
 594         step->granularity == JDWP_STEP_SIZE(MIN)) {
 595         completed = JNI_TRUE;
 596         LOG_STEP(("stepControl_handleStep: completed, into min"));
 597         goto done;
 598     }
 599 
 600     /*
 601      * If we have left the method in which
 602      * stepping started, the step is always complete.
 603      */
 604     if (step->frameExited) {
 605         completed = JNI_TRUE;
 606         LOG_STEP(("stepControl_handleStep: completed, frame exited"));
 607         goto done;
 608     }
 609 
 610     /*
 611      *  Determine where we are on the call stack relative to where
 612      *  we started.
 613      */
 614     currentDepth = getThreadFrameCount(thread);
 615     fromDepth = step->fromStackDepth;
 616 
 617     if (fromDepth > currentDepth) {
 618         /*
 619          * We have returned from the caller. There are cases where
 620          * we don't get frame pop notifications
 621          * (e.g. stepping from opaque frames), and that's when
 622          * this code will be reached. Complete the step->
 623          */
 624         completed = JNI_TRUE;
 625         LOG_STEP(("stepControl_handleStep: completed, fromDepth>currentDepth(%d>%d)", fromDepth, currentDepth));
 626     } else if (fromDepth < currentDepth) {
 627         /* We have dropped into a called method. */
 628         if (   step->depth == JDWP_STEP_DEPTH(INTO)
 629             && (!eventFilter_predictFiltering(step->stepHandlerNode, clazz,
 630                                           (classname = getClassname(clazz))))
 631             && hasLineNumbers(method) ) {
 632 
 633             /* Stepped into a method with lines, so we're done */
 634             completed = JNI_TRUE;
 635             LOG_STEP(("stepControl_handleStep: completed, fromDepth<currentDepth(%d<%d) and into method with lines", fromDepth, currentDepth));
 636         } else {
 637             /*
 638              * We need to continue, but don't want the overhead of step
 639              * events from this method. So, we disable stepping and
 640              * enable a frame pop. If we're stepping into, we also
 641              * enable method enter events because a called frame may be
 642              * where we want to stop.
 643              */
 644             disableStepping(thread);
 645 
 646             if (step->depth == JDWP_STEP_DEPTH(INTO)) {
 647                 step->methodEnterHandlerNode =
 648                     eventHandler_createInternalThreadOnly(
 649                                        EI_METHOD_ENTRY,
 650                                        handleMethodEnterEvent, matchesFiber ? fiber : thread);
 651                 if (step->methodEnterHandlerNode == NULL) {
 652                     EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,
 653                                 "installing event method enter handler");
 654                 }
 655             }
 656             LOG_STEP(("stepControl_handleStep: NotifyFramePop, (fromDepth currentDepth)(%d %d) ", fromDepth, currentDepth));
 657 
 658             error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)
 659                         (gdata->jvmti, thread, 0);
 660             if (error == JVMTI_ERROR_DUPLICATE) {
 661                 error = JVMTI_ERROR_NONE;
 662             } else if (error != JVMTI_ERROR_NONE) {
 663                 EXIT_ERROR(error, "setting up notify frame pop");
 664             }
 665         }
 666         jvmtiDeallocate(classname);
 667         classname = NULL;
 668     } else {
 669         /*
 670          * We are at the same stack depth where stepping started.
 671          * Instruction steps are complete at this point. For line
 672          * steps we must check to see whether we've moved to a
 673          * different line.
 674          */
 675         if (step->granularity == JDWP_STEP_SIZE(MIN)) {
 676             completed = JNI_TRUE;
 677             LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and min", fromDepth));
 678         } else {
 679             if (step->fromLine != -1) {
 680                 jint line = -1;
 681                 jlocation location;
 682                 jmethodID method;
 683                 WITH_LOCAL_REFS(env, 1) {
 684                     jclass clazz;
 685                     error = getFrameLocation(thread,
 686                                         &clazz, &method, &location);
 687                     if ( isMethodObsolete(method)) {
 688                         method = NULL;
 689                         location = -1;
 690                     }
 691                     if (error != JVMTI_ERROR_NONE || location == -1) {
 692                         EXIT_ERROR(error, "getting frame location");
 693                     }
 694                     if ( method == step->method ) {
 695                         LOG_STEP(("stepControl_handleStep: checking line location"));
 696                         log_debugee_location("stepControl_handleStep: checking line loc",
 697                                 thread, method, location);
 698                         line = findLineNumber(thread, location,
 699                                       step->lineEntries, step->lineEntryCount);
 700                     }
 701                     if (line != step->fromLine) {
 702                         completed = JNI_TRUE;
 703                         LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and different line", fromDepth));
 704                     }
 705                 } END_WITH_LOCAL_REFS(env);
 706             } else {
 707                 /*
 708                  * This is a rare case. We have stepped from a location
 709                  * inside a native method to a location within a Java
 710                  * method at the same stack depth. This means that
 711                  * the original native method returned to another
 712                  * native method which, in turn, invoked a Java method.
 713                  *
 714                  * Since the original frame was  native, we were unable
 715                  * to ask for a frame pop event, and, thus, could not
 716                  * set the step->frameExited flag when the original
 717                  * method was done. Instead we end up here
 718                  * and act just as though the frameExited flag was set
 719                  * and complete the step immediately.
 720                  */
 721                 completed = JNI_TRUE;
 722                 LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and no line", fromDepth));
 723             }
 724         }
 725         LOG_STEP(("stepControl_handleStep: finished"));
 726     }
 727 done:
 728     if (completed) {
 729         completeStep(env, thread, step);
 730     }
 731     stepControl_unlock();
 732     return completed;
 733 }
 734 
 735 
 736 void
 737 stepControl_initialize(void)
 738 {
 739     stepLock = debugMonitorCreate("JDWP Step Handler Lock");
 740 }
 741 
 742 void
 743 stepControl_reset(void)
 744 {
 745 }
 746 
 747 /*
 748  * Reset step control request stack depth and line number.
 749  */
 750 void
 751 stepControl_resetRequest(jthread thread)
 752 {
 753 
 754     StepRequest *step;
 755     jvmtiError error;
 756 
 757     LOG_STEP(("stepControl_resetRequest: thread=%p", thread));
 758 
 759     stepControl_lock();
 760 
 761     step = threadControl_getStepRequest(thread);
 762 
 763     if (step != NULL) {
 764         JNIEnv *env;
 765         env = getEnv();
 766         error = initState(env, thread, step);
 767         if (error != JVMTI_ERROR_NONE) {
 768             EXIT_ERROR(error, "initializing step state");
 769         }
 770     } else {
 771         EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step request");
 772     }
 773 
 774     stepControl_unlock();
 775 }
 776 
 777 static void
 778 initEvents(jthread thread, jthread filter_thread, StepRequest *step)
 779 {
 780     /* Need to install frame pop handler and exception catch handler when
 781      * single-stepping is enabled (i.e. step-into or step-over/step-out
 782      * when fromStackDepth > 0).
 783      */
 784     if (step->depth == JDWP_STEP_DEPTH(INTO) || step->fromStackDepth > 0) {
 785         /*
 786          * TO DO: These might be able to applied more selectively to
 787          * boost performance.
 788          */
 789         step->catchHandlerNode = eventHandler_createInternalThreadOnly(
 790                                      EI_EXCEPTION_CATCH,
 791                                      handleExceptionCatchEvent,
 792                                      filter_thread);
 793         JDI_ASSERT(step->framePopHandlerNode == NULL);
 794         step->framePopHandlerNode = eventHandler_createInternalThreadOnly(
 795                                         EI_FRAME_POP,
 796                                         handleFramePopEvent,
 797                                         filter_thread);
 798 
 799         if (step->catchHandlerNode == NULL ||
 800             step->framePopHandlerNode == NULL) {
 801             EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,
 802                         "installing step event handlers");
 803         }
 804 
 805     }
 806     /*
 807      * Initially enable stepping:
 808      * 1) For step into, always
 809      * 2) For step over, unless right after the VM_INIT.
 810      *    Enable stepping for STEP_MIN or STEP_LINE with or without line numbers.
 811      *    If the class is redefined then non EMCP methods may not have line
 812      *    number info. So enable line stepping for non line number so that it
 813      *    behaves like STEP_MIN/STEP_OVER.
 814      * 3) For step out, only if stepping from native, except right after VM_INIT
 815      *
 816      * (right after VM_INIT, a step->over or out is identical to running
 817      * forever)
 818      */
 819     switch (step->depth) {
 820         case JDWP_STEP_DEPTH(INTO):
 821             enableStepping(thread);
 822             break;
 823         case JDWP_STEP_DEPTH(OVER):
 824             if (step->fromStackDepth > 0 && !step->fromNative ) {
 825               enableStepping(thread);
 826             }
 827             break;
 828         case JDWP_STEP_DEPTH(OUT):
 829             if (step->fromNative &&
 830                 (step->fromStackDepth > 0)) {
 831                 enableStepping(thread);
 832             }
 833             break;
 834         default:
 835             JDI_ASSERT(JNI_FALSE);
 836     }
 837 }
 838 
 839 jvmtiError
 840 stepControl_beginStep(JNIEnv *env, jthread filter_thread,  jint size, jint depth,
 841                       HandlerNode *node)
 842 {
 843     StepRequest *step;
 844     jvmtiError error;
 845     jvmtiError error2;
 846     jthread thread;
 847     jboolean is_fiber;
 848 
 849     /* filter_thread could be a fiber. Get the carrier thread it is mounted on. */
 850     is_fiber = isFiber(filter_thread);
 851     if (is_fiber) {
 852         thread = getFiberThread(filter_thread);
 853         if (thread == NULL) {
 854             /* fiber fixme: It is possible for the StepRequest to have been made on an unmounted
 855              * fiber, and currently we don't support this. 
 856              */
 857             LOG_STEP(("stepControl_beginStep: thread is an unmounted fiber(%p)", filter_thread));
 858             return JVMTI_ERROR_INVALID_THREAD;
 859         }
 860     }  else {
 861         thread = filter_thread;
 862     }
 863 
 864     LOG_STEP(("stepControl_beginStep: filter_thread=%p,thread=%p,size=%d,depth=%d",
 865               filter_thread, thread, size, depth));
 866 
 867     eventHandler_lock(); /* for proper lock order */
 868     stepControl_lock();
 869 
 870     /* fiber fixme: we should consider getting the StepRequest from the fiber instead of the thread.
 871      * That way we don't need to copy back and forth in threadControl_mountFiber and
 872      * threadControl_unmountFiber. It would require some additional changes in the step event 
 873      * support to always pass the fiber to threadControl_getStepRequest(). We also need to 
 874      * deal with node->instructionStepMode, referenceing the fiber copy when appropriate. Note
 875      * this will get tricky if you try to single step in both the fiber and thread. With the
 876      * current impl, if you single step in the fiber first, hit a breakpoint while stepping over
 877      * a method call, and then switch to the carrier thread and start to single step there,
 878      * that will clear out the fiber single stepping. If we get the StepRequest
 879      * from the fiber instead, it won't automatically clear out the fiber single stepping
 880      * when you start single stepping in the carrier thread, but it won't work as expected either
 881      * because JVMTI single stepping on the carrier thread will be disabled once the single
 882      * step is complete. We'd need to detect that we were single stepping on the fiber and
 883      * keep JVMTI single stepping enabled, or we need to clear the single stepping state of
 884      * the fiber.
 885      */
 886     step = threadControl_getStepRequest(thread);
 887     if (step == NULL) {
 888         error = AGENT_ERROR_INVALID_THREAD;
 889         /* Normally not getting a StepRequest struct pointer is a fatal error
 890          *   but on a beginStep, we just return an error code.
 891          */
 892     } else {
 893         /*
 894          * In case the thread isn't already suspended, do it again.
 895          */
 896         error = threadControl_suspendThread(thread, JNI_FALSE);
 897         if (error == JVMTI_ERROR_NONE) {
 898             /*
 899              * Overwrite any currently executing step.
 900              */
 901             step->granularity = size;
 902             step->depth = depth;
 903             step->is_fiber = is_fiber;
 904             step->catchHandlerNode = NULL;
 905             step->framePopHandlerNode = NULL;
 906             step->methodEnterHandlerNode = NULL;
 907             step->stepHandlerNode = node;
 908             error = initState(env, thread, step);
 909             if (error == JVMTI_ERROR_NONE) {
 910                 initEvents(thread, filter_thread, step);
 911             }
 912             /* false means it is not okay to unblock the commandLoop thread */
 913             error2 = threadControl_resumeThread(thread, JNI_FALSE);
 914             if (error2 != JVMTI_ERROR_NONE && error == JVMTI_ERROR_NONE) {
 915                 error = error2;
 916             }
 917 
 918             /*
 919              * If everything went ok, indicate a step is pending.
 920              */
 921             if (error == JVMTI_ERROR_NONE) {
 922                 step->pending = JNI_TRUE;
 923             }
 924         } else {
 925             EXIT_ERROR(error, "stepControl_beginStep: cannot suspend thread");
 926         }
 927     }
 928 
 929     stepControl_unlock();
 930     eventHandler_unlock();
 931 
 932     return error;
 933 }
 934 
 935 
 936 static void
 937 clearStep(jthread thread, StepRequest *step)
 938 {
 939     if (step->pending) {
 940 
 941         disableStepping(thread);
 942         if ( step->catchHandlerNode != NULL ) {
 943             (void)eventHandler_free(step->catchHandlerNode);
 944             step->catchHandlerNode = NULL;
 945         }
 946         if ( step->framePopHandlerNode!= NULL ) {
 947             (void)eventHandler_free(step->framePopHandlerNode);
 948             step->framePopHandlerNode = NULL;
 949         }
 950         if ( step->methodEnterHandlerNode != NULL ) {
 951             (void)eventHandler_free(step->methodEnterHandlerNode);
 952             step->methodEnterHandlerNode = NULL;
 953         }
 954         step->pending = JNI_FALSE;
 955 
 956         /*
 957          * Warning: Do not clear step->method, step->lineEntryCount,
 958          *          or step->lineEntries here, they will likely
 959          *          be needed on the next step.
 960          */
 961 
 962     }
 963 }
 964 
 965 jvmtiError
 966 stepControl_endStep(jthread thread)
 967 {
 968     StepRequest *step;
 969     jvmtiError error;
 970 
 971     LOG_STEP(("stepControl_endStep: thread=%p", thread));
 972 
 973     eventHandler_lock(); /* for proper lock order */
 974     stepControl_lock();
 975 
 976     if (isFiber(thread)) {
 977         jthread carrier_thread = getFiberThread(thread);
 978         /* During termination the fiber might not be mounted, so a NULL carrier thead is ok in that case. */
 979         if (carrier_thread != NULL) {
 980             thread = carrier_thread;
 981         }
 982     }
 983     step = threadControl_getStepRequest(thread);
 984     if (step != NULL) {
 985         clearStep(thread, step);
 986         error = JVMTI_ERROR_NONE;
 987     } else {
 988         /* If the stepRequest can't be gotten, then this thread no longer
 989          *   exists, just return, don't die here, this is normal at
 990          *   termination time. Return JVMTI_ERROR_NONE so the thread Ref
 991          *   can be tossed.
 992          */
 993          error = JVMTI_ERROR_NONE;
 994     }
 995 
 996     stepControl_unlock();
 997     eventHandler_unlock();
 998 
 999     return error;
1000 }
1001 
1002 void
1003 stepControl_clearRequest(jthread thread, StepRequest *step)
1004 {
1005     LOG_STEP(("stepControl_clearRequest: thread=%p", thread));
1006     clearStep(thread, step);
1007 }
1008 
1009 void
1010 stepControl_lock(void)
1011 {
1012     debugMonitorEnter(stepLock);
1013 }
1014 
1015 void
1016 stepControl_unlock(void)
1017 {
1018     debugMonitorExit(stepLock);
1019 }