Home | History | Annotate | Download | only in Events
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  */
     18 
     19 package org.apache.harmony.jpda.tests.jdwp.Events;
     20 
     21 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket;
     22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
     23 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
     24 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
     25 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
     26 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
     27 
     28 /**
     29  * JDWP Unit test for SINGLE_STEP event with pending exception.
     30  */
     31 public class SingleStepWithPendingExceptionTest extends JDWPEventTestCase {
     32 
     33     @Override
     34     protected String getDebuggeeClassName() {
     35         return SingleStepWithPendingExceptionDebuggee.class.getName();
     36     }
     37 
     38     /**
     39      * Tests that we properly single-step OUT of a method throwing an exception
     40      * to a catch handler.
     41      *
     42      * We execute the test method once with an EXCEPTION event request to capture the
     43      * location of the catch handler.
     44      * Then we set a BREAKPOINT event in the method throwing the exception and execute
     45      * the test method another time. We wait for hitting the breakpoint then we issue
     46      * a SINGLE_STEP OUT request and check that we stop in the catch handler.
     47      */
     48     public void testSingleStepWithPendingException() {
     49         logWriter.println("=> testSingleStepWithPendingException started");
     50 
     51         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
     52 
     53         // Find debuggee class id.
     54         long refTypeID = getClassIDBySignature(getDebuggeeClassSignature());
     55         logWriter.println("=> Debuggee class = " + getDebuggeeClassName());
     56         logWriter.println("=> referenceTypeID for Debuggee class = " + refTypeID);
     57 
     58         long catchMethodId = getMethodID(refTypeID, "catchMethod");
     59 
     60         // Request exception event.
     61         int exceptionRequestId = setCatchException();
     62 
     63         // Resume debuggee so we hit the breakpoint.
     64         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
     65 
     66         // Wait for exception and remember catch location.
     67         EventPacket eventPacket =
     68                 debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.EXCEPTION);
     69         ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
     70         assertEquals("Expected only one event", 1, parsedEvents.length);
     71         assertEventKindEquals("Expected EXCEPTION event", parsedEvents[0].getEventKind(),
     72                 JDWPConstants.EventKind.EXCEPTION);
     73         assertEquals("Unexpected event", exceptionRequestId, parsedEvents[0].getRequestID());
     74         Location catchHandlerLocation =
     75                 ((ParsedEvent.Event_EXCEPTION)parsedEvents[0]).getCatchLocation();
     76         assertEquals("Invalid location's class", refTypeID, catchHandlerLocation.classID);
     77         assertEquals("Invalid location's method", catchMethodId, catchHandlerLocation.methodID);
     78 
     79         // Remove exception request.
     80         clearEvent(JDWPConstants.EventKind.EXCEPTION, exceptionRequestId, true);
     81 
     82         // Install breakpoint at begin of throwMethod.
     83         int breakpointRequestId = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(refTypeID,
     84                 "throwMethod");
     85 
     86         // Exception event suspended all threads: resume them now.
     87         debuggeeWrapper.resume();
     88 
     89         // Wait for breakpoint.
     90         long threadId = debuggeeWrapper.vmMirror.waitForBreakpoint(breakpointRequestId);
     91 
     92         // Single-step OUT of the throwMethod.
     93         int singleStepRequestId = setSingleStepOut(threadId);
     94 
     95         // Breakpoint event suspended all threads: resume them now.
     96         debuggeeWrapper.resume();
     97 
     98         // Wait for single-step.
     99         eventPacket =
    100                 debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.SINGLE_STEP);
    101         parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
    102         assertEquals("Expected only one event", 1, parsedEvents.length);
    103         assertEventKindEquals("Expected SINGLE_STEP event", parsedEvents[0].getEventKind(),
    104                 JDWPConstants.EventKind.SINGLE_STEP);
    105 
    106         // Check that we reached the catch handler location.
    107         Location singleStepLocation =
    108                 ((ParsedEvent.Event_SINGLE_STEP)parsedEvents[0]).getLocation();
    109         if (!catchHandlerLocation.equals(singleStepLocation)) {
    110             fail("Invalid single-step location: expected " + catchHandlerLocation +
    111                     " but was " + singleStepLocation);
    112         }
    113 
    114         // Remove single-step request.
    115         clearEvent(JDWPConstants.EventKind.SINGLE_STEP, singleStepRequestId, true);
    116 
    117         logWriter.println("==> Resuming debuggee");
    118         resumeDebuggee();
    119         logWriter.println("==> testSingleStepWithPendingException PASSED!");
    120     }
    121 
    122     private int setCatchException() {
    123         ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setException(
    124                 getClassSignature(SingleStepWithPendingExceptionDebuggee.DebuggeeException.class),
    125                 true, true);
    126         checkReplyPacket(replyPacket, "Failed to set EXCEPTION event request");
    127         return replyPacket.getNextValueAsInt();
    128     }
    129 
    130     private int setSingleStepOut(long threadId) {
    131         ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setStep(new String[0], threadId,
    132                 JDWPConstants.StepSize.LINE, JDWPConstants.StepDepth.OUT);
    133         checkReplyPacket(replyPacket, "Failed to set SINGLE_STEP OUT event request");
    134         return replyPacket.getNextValueAsInt();
    135     }
    136 }
    137