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