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 /** 20 * @author Aleksander V. Budniy 21 */ 22 23 /** 24 * Created on 1.05.2006 25 */ 26 package org.apache.harmony.jpda.tests.jdwp.StackFrame; 27 28 import org.apache.harmony.jpda.tests.framework.TestErrorException; 29 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 30 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 32 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 33 import org.apache.harmony.jpda.tests.framework.jdwp.Value; 34 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 35 36 /** 37 * JDWP Unit test for StackFrame.PopFrames command. 38 */ 39 public class PopFrames002Test extends JDWPStackFrameTestCase { 40 41 private String debuggeeSignature = "Lorg/apache/harmony/jpda/tests/jdwp/StackFrame/PopFramesDebuggee;"; 42 43 private String breakpointMethodName = "nestledMethod4"; 44 45 private String methodToPop = "nestledMethod2"; 46 47 private long timeoutToWait = 2000; 48 49 private long timeOfMethodInvocation = timeoutToWait * 5; 50 51 private static final byte NUMBER_OF_FRAMES_TO_POP = 3; 52 getDebuggeeClassName()53 protected String getDebuggeeClassName() { 54 return PopFramesDebuggee.class.getName(); 55 } 56 57 /** 58 * This testcase exercises StackFrame.PopFrames command to discard several frames at once. 59 * <BR>The test starts PopFramesDebuggee class, sets a breakpoint 60 * in 'nestledMethod4', stops at breakpoint and prints stack. 61 * <BR>Then the test performs StackFrame.PopFrame command to discard several frames at once, 62 * prints stack and checks that discarded frames are not returned 63 * by ThreadReference.Frames command. 64 * <BR>Then the test resumes debuggee and checks stop on the same breakpoint. 65 */ testPopSeveralFrames()66 public void testPopSeveralFrames() { 67 logWriter.println("==> testPopSeveralFrames started"); 68 69 //check capability, relevant for this test 70 logWriter.println("=> Check capability: canPopFrames"); 71 debuggeeWrapper.vmMirror.capabilities(); 72 boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canPopFrames; 73 if (!isCapability) { 74 logWriter.println("##WARNING: this VM doesn't possess capability: canPopFrames"); 75 return; 76 } 77 78 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 79 80 // find checked method 81 long refTypeID = getClassIDBySignature(debuggeeSignature); 82 83 logWriter.println("=> Debuggee class = " + getDebuggeeClassName()); 84 85 // long methodID = getMethodID(refTypeID, breakpointMethodName); 86 logWriter.println("=> Set breakpoint at the beginning of " + breakpointMethodName); 87 int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin( 88 refTypeID, breakpointMethodName); 89 90 // release debuggee 91 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 92 93 // receive event in nestledMethod4 94 logWriter.println("=> Wait for breakpoint in " + breakpointMethodName); 95 long breakpointThreadID = debuggeeWrapper.vmMirror 96 .waitForBreakpoint(requestID); 97 98 logWriter.println("=> breakpointThreadID = " + breakpointThreadID); 99 100 // print stack frames 101 logWriter.println(""); 102 logWriter.println("=> Get frames before PopFrames command, thread = " + breakpointThreadID); 103 FrameInfo[] frameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 104 logWriter.println("=> Frames before popFrame"); 105 printStackFrame(frameInfos.length, frameInfos); 106 logWriter.println("=> Number of frames before command: " 107 + frameInfos.length); 108 109 // find stack frame for popped method 110 logWriter.println(""); 111 logWriter.println("=> Find frameID of method = " + methodToPop + " for PopFrames command"); 112 long frameID = 0; 113 long methodID = getMethodID(refTypeID, methodToPop); 114 if (methodID == -1) { 115 logWriter.println("##FAILURE: error during getting methodID of " + methodToPop); 116 } 117 boolean isMethodFound = false; 118 for (int j = 0; j < frameInfos.length; j++) { 119 if (frameInfos[j].location.methodID == methodID) { 120 frameID = frameInfos[j].getFrameID(); 121 isMethodFound = true; 122 break; 123 } 124 } 125 if (!isMethodFound) { 126 logWriter 127 .println("##FAILURE: there is no frame for checked method"); 128 fail("There is no frame for checked method"); 129 } 130 131 logWriter.println("=> frameID for PopFrames command = " + frameID); 132 133 // pop stack frames 134 logWriter.println("=> Pop " + NUMBER_OF_FRAMES_TO_POP + " frames at once"); 135 136 logWriter.println(""); 137 logWriter.println("=> Perform PopFrames command for method = " + methodToPop + " with frameID = " + frameID); 138 jdwpPopFrames(breakpointThreadID, frameID); 139 140 logWriter.println("=> Get frames after PopFrames command, thread = " + breakpointThreadID); 141 FrameInfo[] newFrameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 142 143 logWriter.println(""); 144 logWriter.println("=> Frames after popFrame"); 145 logWriter.println("=> newNumberOfFrames = " + newFrameInfos.length); 146 147 printStackFrame(newFrameInfos.length, newFrameInfos); 148 logWriter.println("=> Check that " + NUMBER_OF_FRAMES_TO_POP + " were discarded"); 149 int numberOfPoppedFrames = frameInfos.length - newFrameInfos.length; 150 assertEquals("not all frames were discarded", numberOfPoppedFrames, 151 NUMBER_OF_FRAMES_TO_POP); 152 153 for (int i = numberOfPoppedFrames; i < (frameInfos.length); i++) { 154 if (frameInfos[i].location.methodID != newFrameInfos[i 155 - numberOfPoppedFrames].location.methodID) { 156 logWriter.println("## FAILURE: frames number " + i + " and " 157 + (i - numberOfPoppedFrames) + " are not equal"); 158 fail("frames number are not equal"); 159 } 160 } 161 162 logWriter.println("=> Ckeck PASSED"); 163 logWriter.println("=> Resume debuggee"); 164 debuggeeWrapper.vmMirror.resume(); 165 166 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 167 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 168 169 logWriter.println("=> Wait for breakpoint in " + breakpointMethodName); 170 breakpointThreadID = debuggeeWrapper.vmMirror 171 .waitForBreakpoint(requestID); 172 173 logWriter.println("=> Resume debuggee"); 174 debuggeeWrapper.vmMirror.resume(); 175 176 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 177 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 178 logWriter.println("==> TEST popSeveralFrames PASSED"); 179 180 } 181 182 /** 183 * This testcase exercises StackFrame.PopFrames command performing it several times. 184 * <BR>The test starts PopFramesDebuggee class, sets a breakpoint 185 * in 'nestledMethod4', stops at breakpoint and prints stack. 186 * <BR>Then the test performs StackFrame.PopFrame command several times 187 * to discard frames one after another, 188 * prints stack and checks that discarded frames are not returned 189 * by ThreadReference.Frames command. 190 * <BR>Then the test resumes debuggee and checks stop on the same breakpoint. 191 */ testPopSeveralTimes()192 public void testPopSeveralTimes() { 193 logWriter.println("==> testPopSeveralTimes started"); 194 195 //check capability, relevant for this test 196 logWriter.println("=> Check capability: canPopFrames"); 197 debuggeeWrapper.vmMirror.capabilities(); 198 boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canPopFrames; 199 if (!isCapability) { 200 logWriter.println("##WARNING: this VM doesn't possess capability: canPopFrames"); 201 return; 202 } 203 // pass nestledMethod1() 204 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 205 206 // find checked method 207 long refTypeID = getClassIDBySignature(debuggeeSignature); 208 209 logWriter.println("=> Debuggee class = " + getDebuggeeClassName()); 210 211 logWriter.println("=> Set breakpoint at the beginning of " + breakpointMethodName); 212 int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin( 213 refTypeID, breakpointMethodName); 214 215 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 216 217 // receive event 218 logWriter.println("=> Wait for breakpoint in " + breakpointMethodName); 219 long breakpointThreadID = debuggeeWrapper.vmMirror 220 .waitForBreakpoint(requestID); 221 222 logWriter.println("=> breakpointThreadID = " + breakpointThreadID); 223 224 // print stack frames 225 logWriter.println(""); 226 logWriter.println("=> Get frames before PopFrames command, thread = " + breakpointThreadID); 227 FrameInfo[] frameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 228 logWriter.println("=> Frames before popFrame"); 229 printStackFrame(frameInfos.length, frameInfos); 230 int framesBeforePop = frameInfos.length; 231 logWriter 232 .println("=> Number of frames before command: " + framesBeforePop); 233 234 logWriter.println(""); 235 logWriter.println("=> Pop " + NUMBER_OF_FRAMES_TO_POP 236 + " frames one after another"); 237 logWriter.println(""); 238 for (int i = 0; i < 3; i++) { 239 logWriter.println("=> Pop frame#" + i); 240 frameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 241 logWriter.println("=> Perform PopFrames command with frameID = " + frameInfos[0].getFrameID()); 242 jdwpPopFrames(breakpointThreadID, frameInfos[0].getFrameID()); 243 } 244 245 logWriter.println("=> Get frames after PopFrames command, thread = " + breakpointThreadID); 246 FrameInfo[] newFrameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 247 248 logWriter.println(""); 249 logWriter.println("=> Frames after popFrame"); 250 logWriter.println("=> newNumberOfFrames = " + newFrameInfos.length); 251 252 printStackFrame(newFrameInfos.length, newFrameInfos); 253 254 logWriter.println("=> Check that " + NUMBER_OF_FRAMES_TO_POP + " frames were discarded"); 255 int numberOfPoppedFrames = framesBeforePop - newFrameInfos.length; 256 assertEquals("not all frames were discarded", numberOfPoppedFrames, 257 NUMBER_OF_FRAMES_TO_POP); 258 259 logWriter.println("=> Resume debuggee"); 260 debuggeeWrapper.vmMirror.resume(); 261 262 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 263 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 264 265 logWriter.println("=> Wait for breakpoint in " + breakpointMethodName); 266 breakpointThreadID = debuggeeWrapper.vmMirror 267 .waitForBreakpoint(requestID); 268 269 logWriter.println("=> Resume debuggee"); 270 debuggeeWrapper.vmMirror.resume(); 271 272 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 273 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 274 275 logWriter.println("==> TEST popSeveralTimes PASSED"); 276 } 277 278 /** 279 * This testcase exercises StackFrame.PopFrames command when thread is not suspended. 280 * <BR>The test starts PopFramesDebuggee class, sets a breakpoint 281 * in 'nestledMethod4', stops at breakpoint and prints stack. 282 * <BR>Then the test performs ClassType.InvokeMethodCommand without waiting reply, and 283 * waits to ensure that method was started. 284 * <BR>During working of method the test performs StackFrame.PopFrames command. 285 * Then the test checks that StackFrame.PopFrames command 286 * returns error: THREAD_NOT_SUSPENDED or INVALID_FRAMEID. 287 * <BR>Next, the test receives reply from invoked method and resumes debuggee.. 288 */ testPopFramesWithInvokeMethods()289 public void testPopFramesWithInvokeMethods() { 290 logWriter.println("==> testPopFramesWithInvokeMethods started"); 291 292 //check capability, relevant for this test 293 logWriter.println("=> Check capability: canPopFrames"); 294 debuggeeWrapper.vmMirror.capabilities(); 295 boolean isCapability = debuggeeWrapper.vmMirror.targetVMCapabilities.canPopFrames; 296 if (!isCapability) { 297 logWriter.println("##WARNING: this VM doesn't possess capability: canPopFrames"); 298 return; 299 } 300 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 301 302 // find checked method 303 long refTypeID = getClassIDBySignature(debuggeeSignature); 304 305 logWriter.println("=> Debuggee class = " + getDebuggeeClassName()); 306 307 logWriter.println("=> Set breakpoint at the beginning of " + breakpointMethodName); 308 int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin( 309 refTypeID, breakpointMethodName); 310 311 // release debuggee 312 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 313 314 // receive event 315 logWriter.println("=> Wait for breakpoint in " + breakpointMethodName); 316 long breakpointThreadID = debuggeeWrapper.vmMirror 317 .waitForBreakpoint(requestID); 318 319 logWriter.println("=> breakpointThreadID = " + breakpointThreadID); 320 321 // print stack frames 322 logWriter.println(""); 323 logWriter.println("=> Get frames before PopFrames command, thread = " + breakpointThreadID); 324 FrameInfo[] frameInfos = jdwpGetFrames(breakpointThreadID, 0, -1); 325 printStackFrame(frameInfos.length, frameInfos); 326 logWriter.println("=> Number of frames before command: " 327 + frameInfos.length); 328 329 // find frameID to pop 330 logWriter.println(""); 331 logWriter.println("=> Find frameID of method = " + methodToPop + " for PopFrames command"); 332 long frameID = 0; 333 long methodID = getMethodID(refTypeID, methodToPop); 334 boolean isMethodFound = false; 335 for (int j = 0; j < frameInfos.length; j++) { 336 if (frameInfos[j].location.methodID == methodID) { 337 frameID = frameInfos[j].getFrameID(); 338 isMethodFound = true; 339 break; 340 } 341 } 342 if (!isMethodFound) { 343 logWriter 344 .println("##FAILURE: there is no frame for checked method"); 345 fail("There is no frame for checked method"); 346 } 347 348 logWriter.println("=> frameID for PopFrames command = " + frameID); 349 350 // create JDWP command for MethodInvoke with a long running method 351 long debuggeeRefTypeID = debuggeeWrapper.vmMirror 352 .getClassID(debuggeeSignature); 353 logWriter.println("=> Find toInvokeMethodID for method: " + PopFramesDebuggee.METHOD_TO_INVOKE_NAME); 354 long toInvokeMethodID = debuggeeWrapper.vmMirror.getMethodID( 355 debuggeeRefTypeID, PopFramesDebuggee.METHOD_TO_INVOKE_NAME); 356 if (toInvokeMethodID == -1) { 357 logWriter 358 .println("## FAILURE: Can NOT get toInvokeMethodID for method: " 359 + PopFramesDebuggee.METHOD_TO_INVOKE_NAME); 360 fail("## Can NOT get toInvokeMethodID"); 361 } 362 logWriter.println("=> toInvokeMethodID = " + toInvokeMethodID); 363 364 int invokeCommandID = 0; 365 CommandPacket invokeCommand = new CommandPacket( 366 JDWPCommands.ClassTypeCommandSet.CommandSetID, 367 JDWPCommands.ClassTypeCommandSet.InvokeMethodCommand); 368 invokeCommand.setNextValueAsClassID(debuggeeRefTypeID); 369 invokeCommand.setNextValueAsThreadID(breakpointThreadID); 370 invokeCommand.setNextValueAsMethodID(toInvokeMethodID); 371 invokeCommand.setNextValueAsInt(1); // args number 372 invokeCommand.setNextValueAsValue(new Value(timeOfMethodInvocation)); 373 invokeCommand 374 .setNextValueAsInt(JDWPConstants.InvokeOptions.INVOKE_SINGLE_THREADED); 375 376 // send MethodInvoke command, but not wait for reply 377 try { 378 logWriter 379 .println("=> Send InvokeMethod command for method: " + PopFramesDebuggee.METHOD_TO_INVOKE_NAME); 380 invokeCommandID = debuggeeWrapper.vmMirror 381 .sendCommand(invokeCommand); 382 } catch (Exception e) { 383 logWriter.println("Exception during invokeCommand: " + e); 384 throw new TestErrorException(e); 385 } 386 387 // wait to ensure that method invocation started 388 logWriter.println("=> Wait " + timeoutToWait 389 + " mls to ensure that method invocation started"); 390 Object waitObj = new Object(); 391 synchronized (waitObj) { 392 try { 393 waitObj.wait(timeoutToWait); 394 } catch (InterruptedException e) { 395 logWriter.println("##Exception while waiting on object: " + e); 396 throw new TestErrorException(e); 397 } 398 } 399 400 // perform PopFrame command 401 logWriter.println("=> Perform PopFrames command for method = " + methodToPop + " with frameID = " + frameID + " and expect errors"); 402 CommandPacket popFramesCommand = new CommandPacket( 403 JDWPCommands.StackFrameCommandSet.CommandSetID, 404 JDWPCommands.StackFrameCommandSet.PopFramesCommand); 405 popFramesCommand.setNextValueAsThreadID(breakpointThreadID); 406 popFramesCommand.setNextValueAsFrameID(frameID); 407 408 ReplyPacket popFrameReply = debuggeeWrapper.vmMirror 409 .performCommand(popFramesCommand); 410 int res = popFrameReply.getErrorCode(); 411 logWriter.println("=> Returned error code: " + res + " (" 412 + JDWPConstants.Error.getName(res) + ")"); 413 414 // check that PopFrames returns error, because thread is resumed by 415 // InvokeMethod 416 if (res == JDWPConstants.Error.NONE) { 417 logWriter 418 .println("##PopFrames command returned no error for thread resumed by InvokeMethod"); 419 fail("##PopFrames command returned no error for thread resumed by InvokeMethod"); 420 } 421 422 logWriter.println("=> Receive reply of invoked method: " + PopFramesDebuggee.METHOD_TO_INVOKE_NAME); 423 try { 424 ReplyPacket reply = debuggeeWrapper.vmMirror 425 .receiveReply(invokeCommandID); 426 checkReplyPacket(reply, "ClassType::InvokeMethod command"); 427 } catch (Exception e) { 428 logWriter 429 .println("##Exception while receiving reply for invoke command: " 430 + e); 431 throw new TestErrorException(e); 432 } 433 434 logWriter.println("=> Resume debuggee"); 435 debuggeeWrapper.vmMirror.resume(); 436 437 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 438 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 439 logWriter.println("==> TEST testPopFramesWithInvokeMethods PASSED"); 440 } 441 printStackFrame(int NumberOfFrames, FrameInfo[] frameInfos)442 void printStackFrame(int NumberOfFrames, FrameInfo[] frameInfos) { 443 for (int i = 0; i < NumberOfFrames; i++) { 444 logWriter.println(" "); 445 logWriter 446 .println("=> #" + i + " frameID=" + frameInfos[i].frameID); 447 String methodName = getMethodName(frameInfos[i].location.classID, 448 frameInfos[i].location.methodID); 449 logWriter.println("=> method name=" + methodName); 450 } 451 logWriter.println(""); 452 } 453 } 454