1/* 2 * Copyright (c) 2007, 2017, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24// THIS TEST IS LINE NUMBER SENSITIVE 25 26/** 27 * @test 28 * @bug 4300412 29 * @summary Test GetLocal* and SetLocal* functions 30 * @author Serguei Spitsyn 31 * 32 * @run build TestScaffold VMConnection TargetListener TargetAdapter 33 * @run compile -g GetSetLocalTest.java 34 * @run driver GetSetLocalTest 35 */ 36import com.sun.jdi.*; 37import com.sun.jdi.event.*; 38import com.sun.jdi.request.*; 39 40import java.util.*; 41 42 /********** target program **********/ 43 44class GetSetLocalTarg { 45 public static void main(String[] args){ 46 int intVar = 10; 47 System.out.println("GetSetLocalTarg: Started"); 48 intVar = staticMeth(intVar); 49 System.out.println("GetSetLocalTarg: Finished"); 50 } 51 52 /* 53 * The line numbers of this method *MUST NOT* be changed 54 * because the testing algorithm counts on this layout! 55 * It's in calls to resumeTo("GetSetLocalTarg", line). 56 */ 57 public static int staticMeth(int intArg) { 58 System.out.println("staticMeth: Started"); 59 int result; 60 { 61 { boolean bool_1 = false; 62 intArg++; // START_LINE 63 } 64 65 boolean bool_2 = true; 66 intArg++; 67 } 68 { 69 { byte byte_1 = 1; 70 intArg++; 71 } 72 73 byte byte_2 = 2; 74 intArg++; 75 } 76 { 77 { char char_1 = '1'; 78 intArg++; 79 } 80 81 char char_2 = '2'; 82 intArg++; 83 } 84 { 85 { short short_1 = 1; 86 intArg++; 87 } 88 89 short short_2 = 2; 90 intArg++; 91 } 92 { 93 { int int_1 = 1; 94 intArg++; 95 } 96 97 int int_2 = 2; 98 intArg++; 99 } 100 { 101 { long long_1 = 1; 102 intArg++; 103 } 104 105 long long_2 = 2; 106 intArg++; 107 } 108 { 109 { float float_1 = 1; 110 intArg++; 111 } 112 113 float float_2 = 2; 114 intArg++; 115 } 116 { 117 { double double_1 = 1; 118 intArg++; 119 } 120 121 double double_2 = 2; 122 intArg++; 123 } 124 { 125 { String string_1 = "1"; 126 intArg++; 127 } 128 129 String string_2 = "2"; 130 intArg++; 131 } 132 { 133 { Object obj_1 = new Object(); 134 intArg++; 135 } 136 137 Object obj_2 = new Object(); 138 intArg++; // STOP_LINE. Last stop is at this point. 139 // Only obj_2 and intArg are valid 140 // Note: even result is not valid here! 141 } 142 result = 10; // <- This is first init of result var 143 System.out.println("staticMeth: Finished"); 144 return result; 145 } 146} 147 148 149 /********** test program **********/ 150 151public class GetSetLocalTest extends TestScaffold { 152 static final int START_LINE = 62; 153 static final int STOP_LINE = 138; 154 ReferenceType targetClass; 155 ThreadReference mainThread; 156 157 GetSetLocalTest (String args[]) { 158 super(args); 159 } 160 161 public static void main(String[] args) throws Exception { 162 new GetSetLocalTest(args).startTests(); 163 } 164 165 /********** test assist **********/ 166 167 Method getMethod(String className, String methodName) { 168 List refs = vm().classesByName(className); 169 if (refs.size() != 1) { 170 failure(" Failure: " + refs.size() + 171 " ReferenceTypes named: " + className); 172 return null; 173 } 174 ReferenceType refType = (ReferenceType)refs.get(0); 175 List meths = refType.methodsByName(methodName); 176 if (meths.size() != 1) { 177 failure(" Failure: " + meths.size() + 178 " methods named: " + methodName); 179 return null; 180 } 181 return (Method)meths.get(0); 182 } 183 184 List printAllVariables(String className, String methodName) throws Exception { 185 println("printAllVariables for method: " + className + "." + methodName); 186 Method method = getMethod(className, methodName); 187 List localVars; 188 try { 189 localVars = method.variables(); 190 println(" Success: got a list of all method variables: " + methodName); 191 } 192 catch (com.sun.jdi.AbsentInformationException ex) { 193 failure(" Failure: AbsentInformationException has been thrown"); 194 return null; 195 } 196 197 int index = 0; 198 for (Iterator it = localVars.iterator(); it.hasNext();) { 199 LocalVariable lv = (LocalVariable) it.next(); 200 printOneVariable(lv, index++); 201 } 202 println(""); 203 return localVars; 204 } 205 206 void checkGetSetAllVariables(List localVars, StackFrame frame) throws Exception { 207 println("\n checkGetSetAllVariables for method at particular frame location: "); 208 int index = 0; 209 for (Iterator it = localVars.iterator(); it.hasNext();) { 210 LocalVariable lv = (LocalVariable) it.next(); 211 String lv_name = lv.name(); 212 print(" Variable " + lv_name); 213 try { 214 Value val = frame.getValue(lv); 215 frame.setValue(lv, val); 216 println(" has been get/set"); 217 if (lv_name.compareTo("intArg") != 0 && 218 lv_name.compareTo("obj_2") != 0) { 219 failure(" Failure: AbsentInformationException is expected"); 220 } 221 } catch (java.lang.IllegalArgumentException ex) { 222 println(" is not valid"); 223 if (lv_name.compareTo("intArg") == 0 && 224 lv_name.compareTo("obj_2") == 0) { 225 failure(" Failure: AbsentInformationException was not expected"); 226 } 227 } 228 } 229 println(""); 230 } 231 232 void printOneVariable(LocalVariable lv, int index) throws Exception { 233 String tyname = lv.typeName(); 234 println(""); 235 println(" Var name: " + lv.name()); 236 println(" Var type: " + tyname); 237 println(" Var index: " + index); 238 println(" Signature: " + lv.type().signature()); 239 // Sorry, there is no way to get (and print) 240 // a local variable slot numbers using JDI! 241 } 242 243 void printFrameVariables(StackFrame frame) throws Exception { 244 int index = 0; 245 List localVars = frame.visibleVariables(); 246 println("\n Visible variables at this point are: "); 247 248 for (Iterator it = localVars.iterator(); it.hasNext();) { 249 LocalVariable lv = (LocalVariable) it.next(); 250 printOneVariable(lv, index++); 251 println(" Var value: " + frame.getValue(lv)); 252 } 253 } 254 255 BooleanValue incrValue(BooleanValue val) { 256 boolean value = val.value(); 257 return vm().mirrorOf(!value); 258 } 259 260 ByteValue incrValue(ByteValue val) { 261 byte value = val.value(); 262 return vm().mirrorOf(++value); 263 } 264 265 CharValue incrValue(CharValue val) { 266 char value = val.value(); 267 return vm().mirrorOf(++value); 268 } 269 270 ShortValue incrValue(ShortValue val) { 271 short value = val.value(); 272 return vm().mirrorOf(++value); 273 } 274 275 IntegerValue incrValue(IntegerValue val) { 276 int value = val.value(); 277 return vm().mirrorOf(++value); 278 } 279 280 LongValue incrValue(LongValue val) { 281 long value = val.value(); 282 return vm().mirrorOf(++value); 283 } 284 285 FloatValue incrValue(FloatValue val) { 286 float value = val.value(); 287 return vm().mirrorOf(++value); 288 } 289 290 DoubleValue incrValue(DoubleValue val) { 291 double value = val.value(); 292 return vm().mirrorOf(++value); 293 } 294 295 StringReference incrValue(StringReference val) { 296 String newstr = new String("Set String ").concat(val.value()); 297 return vm().mirrorOf(newstr); 298 } 299 300 void checkSetBooleanTypes(StackFrame frame, LocalVariable lv) throws Exception { 301 BooleanValue get = (BooleanValue) frame.getValue(lv); 302 BooleanValue set = incrValue(get); 303 frame.setValue(lv, set); 304 305 // To get the new value which has been set 306 get = (BooleanValue) frame.getValue(lv); 307 println(" Var Set: " + set); 308 println(" Var Get: " + get); 309 println(""); 310 boolean v1 = get.value(); 311 boolean v2 = set.value(); 312 313 // Check if set was done properly 314 if (v1 == v2) { 315 println(" Success: Value was set correctly!"); 316 } else { 317 failure(" Failure: Value was NOT set correctly!"); 318 } 319 println(""); 320 } 321 322 void checkSetByteTypes(StackFrame frame, LocalVariable lv) throws Exception { 323 ByteValue get = (ByteValue) frame.getValue(lv); 324 ByteValue set = incrValue(get); 325 frame.setValue(lv, set); 326 327 // To get the new value which has been set 328 get = (ByteValue) frame.getValue(lv); 329 println(" Var Set: " + set); 330 println(" Var Get: " + get); 331 println(""); 332 byte v1 = get.value(); 333 byte v2 = set.value(); 334 335 // Check if set was done properly 336 if (v1 == v2) { 337 println(" Success: Value was set correctly!"); 338 } else { 339 failure(" Failure: Value was NOT set correctly!"); 340 } 341 println(""); 342 } 343 344 void checkSetCharTypes(StackFrame frame, LocalVariable lv) throws Exception { 345 CharValue get = (CharValue) frame.getValue(lv); 346 CharValue set = incrValue(get); 347 frame.setValue(lv, set); 348 349 // To get the new value which has been set 350 get = (CharValue) frame.getValue(lv); 351 println(" Var Set: " + set); 352 println(" Var Get: " + get); 353 println(""); 354 char v1 = get.value(); 355 char v2 = set.value(); 356 357 // Check if set was done properly 358 if (v1 == v2) { 359 println(" Success: Value was set correctly!"); 360 } else { 361 failure(" Failure: Value was NOT set correctly!"); 362 } 363 println(""); 364 } 365 366 void checkSetShortTypes(StackFrame frame, LocalVariable lv) throws Exception { 367 ShortValue get = (ShortValue) frame.getValue(lv); 368 ShortValue set = incrValue(get); 369 frame.setValue(lv, set); 370 371 // To get the new value which has been set 372 get = (ShortValue) frame.getValue(lv); 373 println(" Var Set: " + set); 374 println(" Var Get: " + get); 375 println(""); 376 short v1 = get.value(); 377 short v2 = set.value(); 378 379 // Check if set was done properly 380 if (v1 == v2) { 381 println(" Success: Value was set correctly!"); 382 } else { 383 failure(" Failure: Value was NOT set correctly!"); 384 } 385 println(""); 386 } 387 388 void checkSetIntegerTypes(StackFrame frame, LocalVariable lv) throws Exception { 389 IntegerValue get = (IntegerValue) frame.getValue(lv); 390 IntegerValue set = incrValue(get); 391 frame.setValue(lv, set); 392 393 // To get the new value which has been set 394 get = (IntegerValue) frame.getValue(lv); 395 println(" Var Set: " + set); 396 println(" Var Get: " + get); 397 println(""); 398 int v1 = get.value(); 399 int v2 = set.value(); 400 401 // Check if set was done properly 402 if (v1 == v2) { 403 println(" Success: Value was set correctly!"); 404 } else { 405 failure(" Failure: Value was NOT set correctly!"); 406 } 407 println(""); 408 } 409 410 void checkSetLongTypes(StackFrame frame, LocalVariable lv) throws Exception { 411 LongValue get = (LongValue) frame.getValue(lv); 412 LongValue set = incrValue(get); 413 frame.setValue(lv, set); 414 415 // To get the new value which has been set 416 get = (LongValue) frame.getValue(lv); 417 println(" Var Set: " + set); 418 println(" Var Get: " + get); 419 println(""); 420 long v1 = get.value(); 421 long v2 = set.value(); 422 423 // Check if set was done properly 424 if (v1 == v2) { 425 println(" Success: Value was set correctly!"); 426 } else { 427 failure(" Failure: Value was NOT set correctly!"); 428 } 429 println(""); 430 } 431 432 void checkSetFloatTypes(StackFrame frame, LocalVariable lv) throws Exception { 433 FloatValue get = (FloatValue) frame.getValue(lv); 434 FloatValue set = incrValue(get); 435 frame.setValue(lv, set); 436 437 // To get the new value which has been set 438 get = (FloatValue) frame.getValue(lv); 439 println(" Var Set: " + set); 440 println(" Var Get: " + get); 441 println(""); 442 float v1 = get.value(); 443 float v2 = set.value(); 444 445 // Check if set was done properly 446 if (v1 == v2) { 447 println(" Success: Value was set correctly!"); 448 } else { 449 failure(" Failure: Value was NOT set correctly!"); 450 } 451 println(""); 452 } 453 454 void checkSetDoubleTypes(StackFrame frame, LocalVariable lv) throws Exception { 455 DoubleValue get = (DoubleValue) frame.getValue(lv); 456 DoubleValue set = incrValue(get); 457 frame.setValue(lv, set); 458 459 // To get the new value which has been set 460 get = (DoubleValue) frame.getValue(lv); 461 println(" Var Set: " + set); 462 println(" Var Get: " + get); 463 println(""); 464 double v1 = get.value(); 465 double v2 = set.value(); 466 467 // Check if set was done properly 468 if (v1 == v2) { 469 println(" Success: Value was set correctly!"); 470 } else { 471 failure(" Failure: Value was NOT set correctly!"); 472 } 473 println(""); 474 } 475 476 void checkSetStringTypes(StackFrame frame, LocalVariable lv) throws Exception { 477 StringReference get = (StringReference) frame.getValue(lv); 478 StringReference set = incrValue((StringReference) frame.getValue(lv)); 479 frame.setValue(lv, set); 480 481 // To get the new value which has been set 482 get = (StringReference) frame.getValue(lv); 483 println(" Var Set: " + set); 484 println(" Var Get: " + get); 485 println(""); 486 String str1 = get.value(); 487 String str2 = set.value(); 488 489 // Check if set was done properly 490 if (str1.compareTo(str2) == 0) { 491 println(" Success: String was set correctly!"); 492 } else { 493 failure(" Failure: String was NOT set correctly!"); 494 } 495 println(""); 496 } 497 498 void checkSetObjectTypes(StackFrame frame, LocalVariable lv) throws Exception { 499 ObjectReference get = (ObjectReference) frame.getValue(lv); 500 ObjectReference set = get; // FIXME: Don't know how to create a mirror of Object 501 frame.setValue(lv, set); 502 503 // To get the new value which has been set 504 get = (ObjectReference) frame.getValue(lv); 505 println(" Var Set: " + set); 506 println(" Var Get: " + get); 507 println(""); 508 509 if (set.uniqueID() == get.uniqueID()) { 510 println(" Success: Object was set correctly!"); 511 } else { 512 failure(" Failure: Object was NOT set correctly!"); 513 } 514 println(""); 515 } 516 517 void negativeIntegerCheck(StackFrame frame, LocalVariable lv) throws Exception { 518 try { 519 IntegerValue get = (IntegerValue) frame.getValue(lv); 520 println(" Get: No ClassCastException error!"); 521 } catch(java.lang.ClassCastException ex) { 522 println(" Success: Get: ClassCastException error has cought as expected!"); 523 } 524 try { 525 IntegerValue set = vm().mirrorOf((int) 0x3F); 526 frame.setValue(lv, set); 527 println(" Set: No InvalidTypeException with Integer error!"); 528 } catch(com.sun.jdi.InvalidTypeException ex) { 529 println(" Success: Set: InvalidTypeException with Integer error has cought as expected!"); 530 } 531 } 532 533 void negativeFloatCheck(StackFrame frame, LocalVariable lv) throws Exception { 534 try { 535 FloatValue get = (FloatValue) frame.getValue(lv); 536 println(" Get: No ClassCastException error!"); 537 } catch(java.lang.ClassCastException ex) { 538 println(" Success: Get: ClassCastException with Float error has cought as expected!"); 539 } 540 try { 541 FloatValue set = vm().mirrorOf(1.2345f); 542 frame.setValue(lv, set); 543 println(" Set: No InvalidTypeException with Float error!"); 544 } catch(com.sun.jdi.InvalidTypeException ex) { 545 println(" Success: Set: InvalidTypeException error has cought as expected!"); 546 } 547 } 548 549 void negativeDoubleCheck(StackFrame frame, LocalVariable lv) throws Exception { 550 try { 551 DoubleValue get = (DoubleValue) frame.getValue(lv); 552 println(" Get: No ClassCastException error!"); 553 } catch(java.lang.ClassCastException ex) { 554 println(" Success: Get: ClassCastException with Double error has cought as expected!"); 555 } 556 try { 557 DoubleValue set = vm().mirrorOf(1.2345E02); 558 frame.setValue(lv, set); 559 println(" Set: No InvalidTypeException with Double error!"); 560 } catch(com.sun.jdi.InvalidTypeException ex) { 561 println(" Success: Set: InvalidTypeException error has cought as expected!"); 562 } 563 } 564 565 void checkSetFrameVariables(StackFrame frame) throws Exception { 566 List localVars = frame.visibleVariables(); 567 int index = 0; 568 println("\n Set variable values:"); 569 570 for (Iterator it = localVars.iterator(); it.hasNext();index++) { 571 LocalVariable lv = (LocalVariable) it.next(); 572 String signature = lv.type().signature(); 573 574 switch (signature.charAt(0)) { 575 case 'Z': // Boolean Type 576 checkSetBooleanTypes(frame, lv); 577 negativeIntegerCheck(frame, lv); 578 negativeFloatCheck(frame, lv); 579 negativeDoubleCheck(frame, lv); 580 break; 581 case 'B': // Byte Type 582 checkSetByteTypes(frame, lv); 583 negativeIntegerCheck(frame, lv); 584 negativeFloatCheck(frame, lv); 585 negativeDoubleCheck(frame, lv); 586 break; 587 case 'C': // Char Type 588 checkSetCharTypes(frame, lv); 589 negativeIntegerCheck(frame, lv); 590 negativeFloatCheck(frame, lv); 591 negativeDoubleCheck(frame, lv); 592 break; 593 case 'S': // Short Type 594 checkSetShortTypes(frame, lv); 595 negativeIntegerCheck(frame, lv); 596 negativeFloatCheck(frame, lv); 597 negativeDoubleCheck(frame, lv); 598 break; 599 case 'I': // Integer Type 600 checkSetIntegerTypes(frame, lv); 601 if (index > 0) { // To skip integer method parameter 602 negativeFloatCheck(frame, lv); 603 negativeDoubleCheck(frame, lv); 604 } 605 break; 606 case 'J': // Long Type 607 checkSetLongTypes(frame, lv); 608 negativeIntegerCheck(frame, lv); 609 negativeFloatCheck(frame, lv); 610 negativeDoubleCheck(frame, lv); 611 break; 612 case 'F': // Float Type 613 checkSetFloatTypes(frame, lv); 614 negativeIntegerCheck(frame, lv); 615 negativeDoubleCheck(frame, lv); 616 break; 617 case 'D': // Double Type 618 checkSetDoubleTypes(frame, lv); 619 negativeIntegerCheck(frame, lv); 620 negativeFloatCheck(frame, lv); 621 break; 622 case 'L': 623 if (signature.compareTo("Ljava/lang/String;") == 0) { 624 checkSetStringTypes(frame, lv); 625 negativeIntegerCheck(frame, lv); 626 negativeFloatCheck(frame, lv); 627 } 628 if (signature.compareTo("Ljava/lang/Object;") == 0) { 629 checkSetObjectTypes(frame, lv); 630 negativeIntegerCheck(frame, lv); 631 negativeFloatCheck(frame, lv); 632 } 633 break; 634 default: 635 printOneVariable(lv, index); 636 failure(" Failure: List of local variables has a wrong entry!"); 637 }; 638 } 639 } 640 641 642 /********** test core **********/ 643 644 protected void runTests() throws Exception { 645 646 /* 647 * Get to the top of main() to determine targetClass and mainThread 648 */ 649 BreakpointEvent bpe = startToMain("GetSetLocalTarg"); 650 println("startToMain(GetSetLocalTarg)"); 651 652 List localVars = printAllVariables("GetSetLocalTarg", "staticMeth"); 653 654 targetClass = bpe.location().declaringType(); 655 println("targetClass"); 656 657 mainThread = bpe.thread(); 658 println("mainThread"); 659 660 EventRequestManager erm = vm().eventRequestManager(); 661 println("EventRequestManager"); 662 StackFrame frame = null; 663 664 for (int line = START_LINE; line <= STOP_LINE; line += 4) { 665 println("\n resumeTo(GetSetLocalTarg, " + line + ")"); 666 bpe = resumeTo("GetSetLocalTarg", line); 667 frame = bpe.thread().frame(0); 668 printFrameVariables(frame); 669 checkSetFrameVariables(frame); 670 } 671 // Check if we can Get/Set all local vars using last frame state 672 checkGetSetAllVariables(localVars, frame); 673 674 /* 675 * resume until the end 676 */ 677 listenUntilVMDisconnect(); 678 679 /* 680 * deal with results of test 681 * if anything has called failure("foo") testFailed will be true 682 */ 683 if (!testFailed) { 684 println("GetSetLocalTest: passed"); 685 } else { 686 throw new Exception("GetSetLocalTest: failed"); 687 } 688 } 689} 690