| /* |
| * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| // THIS TEST IS LINE NUMBER SENSITIVE |
| |
| /** |
| * @test |
| * @bug 4300412 |
| * @summary Test GetLocal* and SetLocal* functions |
| * @author Serguei Spitsyn |
| * |
| * @run build TestScaffold VMConnection TargetListener TargetAdapter |
| * @run compile -g GetSetLocalTest.java |
| * @run driver GetSetLocalTest |
| */ |
| import com.sun.jdi.*; |
| import com.sun.jdi.event.*; |
| import com.sun.jdi.request.*; |
| |
| import java.util.*; |
| |
| /********** target program **********/ |
| |
| class GetSetLocalTarg { |
| public static void main(String[] args){ |
| int intVar = 10; |
| System.out.println("GetSetLocalTarg: Started"); |
| intVar = staticMeth(intVar); |
| System.out.println("GetSetLocalTarg: Finished"); |
| } |
| |
| /* |
| * The line numbers of this method *MUST NOT* be changed |
| * because the testing algorithm counts on this layout! |
| * It's in calls to resumeTo("GetSetLocalTarg", line). |
| */ |
| public static int staticMeth(int intArg) { |
| System.out.println("staticMeth: Started"); |
| int result; |
| { |
| { boolean bool_1 = false; |
| intArg++; // START_LINE |
| } |
| |
| boolean bool_2 = true; |
| intArg++; |
| } |
| { |
| { byte byte_1 = 1; |
| intArg++; |
| } |
| |
| byte byte_2 = 2; |
| intArg++; |
| } |
| { |
| { char char_1 = '1'; |
| intArg++; |
| } |
| |
| char char_2 = '2'; |
| intArg++; |
| } |
| { |
| { short short_1 = 1; |
| intArg++; |
| } |
| |
| short short_2 = 2; |
| intArg++; |
| } |
| { |
| { int int_1 = 1; |
| intArg++; |
| } |
| |
| int int_2 = 2; |
| intArg++; |
| } |
| { |
| { long long_1 = 1; |
| intArg++; |
| } |
| |
| long long_2 = 2; |
| intArg++; |
| } |
| { |
| { float float_1 = 1; |
| intArg++; |
| } |
| |
| float float_2 = 2; |
| intArg++; |
| } |
| { |
| { double double_1 = 1; |
| intArg++; |
| } |
| |
| double double_2 = 2; |
| intArg++; |
| } |
| { |
| { String string_1 = "1"; |
| intArg++; |
| } |
| |
| String string_2 = "2"; |
| intArg++; |
| } |
| { |
| { Object obj_1 = new Object(); |
| intArg++; |
| } |
| |
| Object obj_2 = new Object(); |
| intArg++; // STOP_LINE. Last stop is at this point. |
| // Only obj_2 and intArg are valid |
| // Note: even result is not valid here! |
| } |
| result = 10; // <- This is first init of result var |
| System.out.println("staticMeth: Finished"); |
| return result; |
| } |
| } |
| |
| |
| /********** test program **********/ |
| |
| public class GetSetLocalTest extends TestScaffold { |
| static final int START_LINE = 62; |
| static final int STOP_LINE = 138; |
| ReferenceType targetClass; |
| ThreadReference mainThread; |
| |
| GetSetLocalTest (String args[]) { |
| super(args); |
| } |
| |
| public static void main(String[] args) throws Exception { |
| new GetSetLocalTest(args).startTests(); |
| } |
| |
| /********** test assist **********/ |
| |
| Method getMethod(String className, String methodName) { |
| List refs = vm().classesByName(className); |
| if (refs.size() != 1) { |
| failure(" Failure: " + refs.size() + |
| " ReferenceTypes named: " + className); |
| return null; |
| } |
| ReferenceType refType = (ReferenceType)refs.get(0); |
| List meths = refType.methodsByName(methodName); |
| if (meths.size() != 1) { |
| failure(" Failure: " + meths.size() + |
| " methods named: " + methodName); |
| return null; |
| } |
| return (Method)meths.get(0); |
| } |
| |
| List printAllVariables(String className, String methodName) throws Exception { |
| println("printAllVariables for method: " + className + "." + methodName); |
| Method method = getMethod(className, methodName); |
| List localVars; |
| try { |
| localVars = method.variables(); |
| println(" Success: got a list of all method variables: " + methodName); |
| } |
| catch (com.sun.jdi.AbsentInformationException ex) { |
| failure(" Failure: AbsentInformationException has been thrown"); |
| return null; |
| } |
| |
| int index = 0; |
| for (Iterator it = localVars.iterator(); it.hasNext();) { |
| LocalVariable lv = (LocalVariable) it.next(); |
| printOneVariable(lv, index++); |
| } |
| println(""); |
| return localVars; |
| } |
| |
| void checkGetSetAllVariables(List localVars, StackFrame frame) throws Exception { |
| println("\n checkGetSetAllVariables for method at particular frame location: "); |
| int index = 0; |
| for (Iterator it = localVars.iterator(); it.hasNext();) { |
| LocalVariable lv = (LocalVariable) it.next(); |
| String lv_name = lv.name(); |
| print(" Variable " + lv_name); |
| try { |
| Value val = frame.getValue(lv); |
| frame.setValue(lv, val); |
| println(" has been get/set"); |
| if (lv_name.compareTo("intArg") != 0 && |
| lv_name.compareTo("obj_2") != 0) { |
| failure(" Failure: AbsentInformationException is expected"); |
| } |
| } catch (java.lang.IllegalArgumentException ex) { |
| println(" is not valid"); |
| if (lv_name.compareTo("intArg") == 0 && |
| lv_name.compareTo("obj_2") == 0) { |
| failure(" Failure: AbsentInformationException was not expected"); |
| } |
| } |
| } |
| println(""); |
| } |
| |
| void printOneVariable(LocalVariable lv, int index) throws Exception { |
| String tyname = lv.typeName(); |
| println(""); |
| println(" Var name: " + lv.name()); |
| println(" Var type: " + tyname); |
| println(" Var index: " + index); |
| println(" Signature: " + lv.type().signature()); |
| // Sorry, there is no way to get (and print) |
| // a local variable slot numbers using JDI! |
| } |
| |
| void printFrameVariables(StackFrame frame) throws Exception { |
| int index = 0; |
| List localVars = frame.visibleVariables(); |
| println("\n Visible variables at this point are: "); |
| |
| for (Iterator it = localVars.iterator(); it.hasNext();) { |
| LocalVariable lv = (LocalVariable) it.next(); |
| printOneVariable(lv, index++); |
| println(" Var value: " + frame.getValue(lv)); |
| } |
| } |
| |
| BooleanValue incrValue(BooleanValue val) { |
| boolean value = val.value(); |
| return vm().mirrorOf(!value); |
| } |
| |
| ByteValue incrValue(ByteValue val) { |
| byte value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| CharValue incrValue(CharValue val) { |
| char value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| ShortValue incrValue(ShortValue val) { |
| short value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| IntegerValue incrValue(IntegerValue val) { |
| int value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| LongValue incrValue(LongValue val) { |
| long value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| FloatValue incrValue(FloatValue val) { |
| float value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| DoubleValue incrValue(DoubleValue val) { |
| double value = val.value(); |
| return vm().mirrorOf(++value); |
| } |
| |
| StringReference incrValue(StringReference val) { |
| String newstr = new String("Set String ").concat(val.value()); |
| return vm().mirrorOf(newstr); |
| } |
| |
| void checkSetBooleanTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| BooleanValue get = (BooleanValue) frame.getValue(lv); |
| BooleanValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (BooleanValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| boolean v1 = get.value(); |
| boolean v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetByteTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| ByteValue get = (ByteValue) frame.getValue(lv); |
| ByteValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (ByteValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| byte v1 = get.value(); |
| byte v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetCharTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| CharValue get = (CharValue) frame.getValue(lv); |
| CharValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (CharValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| char v1 = get.value(); |
| char v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetShortTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| ShortValue get = (ShortValue) frame.getValue(lv); |
| ShortValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (ShortValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| short v1 = get.value(); |
| short v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetIntegerTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| IntegerValue get = (IntegerValue) frame.getValue(lv); |
| IntegerValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (IntegerValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| int v1 = get.value(); |
| int v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetLongTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| LongValue get = (LongValue) frame.getValue(lv); |
| LongValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (LongValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| long v1 = get.value(); |
| long v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetFloatTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| FloatValue get = (FloatValue) frame.getValue(lv); |
| FloatValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (FloatValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| float v1 = get.value(); |
| float v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetDoubleTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| DoubleValue get = (DoubleValue) frame.getValue(lv); |
| DoubleValue set = incrValue(get); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (DoubleValue) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| double v1 = get.value(); |
| double v2 = set.value(); |
| |
| // Check if set was done properly |
| if (v1 == v2) { |
| println(" Success: Value was set correctly!"); |
| } else { |
| failure(" Failure: Value was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetStringTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| StringReference get = (StringReference) frame.getValue(lv); |
| StringReference set = incrValue((StringReference) frame.getValue(lv)); |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (StringReference) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| String str1 = get.value(); |
| String str2 = set.value(); |
| |
| // Check if set was done properly |
| if (str1.compareTo(str2) == 0) { |
| println(" Success: String was set correctly!"); |
| } else { |
| failure(" Failure: String was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void checkSetObjectTypes(StackFrame frame, LocalVariable lv) throws Exception { |
| ObjectReference get = (ObjectReference) frame.getValue(lv); |
| ObjectReference set = get; // FIXME: Don't know how to create a mirror of Object |
| frame.setValue(lv, set); |
| |
| // To get the new value which has been set |
| get = (ObjectReference) frame.getValue(lv); |
| println(" Var Set: " + set); |
| println(" Var Get: " + get); |
| println(""); |
| |
| if (set.uniqueID() == get.uniqueID()) { |
| println(" Success: Object was set correctly!"); |
| } else { |
| failure(" Failure: Object was NOT set correctly!"); |
| } |
| println(""); |
| } |
| |
| void negativeIntegerCheck(StackFrame frame, LocalVariable lv) throws Exception { |
| try { |
| IntegerValue get = (IntegerValue) frame.getValue(lv); |
| println(" Get: No ClassCastException error!"); |
| } catch(java.lang.ClassCastException ex) { |
| println(" Success: Get: ClassCastException error has cought as expected!"); |
| } |
| try { |
| IntegerValue set = vm().mirrorOf((int) 0x3F); |
| frame.setValue(lv, set); |
| println(" Set: No InvalidTypeException with Integer error!"); |
| } catch(com.sun.jdi.InvalidTypeException ex) { |
| println(" Success: Set: InvalidTypeException with Integer error has cought as expected!"); |
| } |
| } |
| |
| void negativeFloatCheck(StackFrame frame, LocalVariable lv) throws Exception { |
| try { |
| FloatValue get = (FloatValue) frame.getValue(lv); |
| println(" Get: No ClassCastException error!"); |
| } catch(java.lang.ClassCastException ex) { |
| println(" Success: Get: ClassCastException with Float error has cought as expected!"); |
| } |
| try { |
| FloatValue set = vm().mirrorOf(1.2345f); |
| frame.setValue(lv, set); |
| println(" Set: No InvalidTypeException with Float error!"); |
| } catch(com.sun.jdi.InvalidTypeException ex) { |
| println(" Success: Set: InvalidTypeException error has cought as expected!"); |
| } |
| } |
| |
| void negativeDoubleCheck(StackFrame frame, LocalVariable lv) throws Exception { |
| try { |
| DoubleValue get = (DoubleValue) frame.getValue(lv); |
| println(" Get: No ClassCastException error!"); |
| } catch(java.lang.ClassCastException ex) { |
| println(" Success: Get: ClassCastException with Double error has cought as expected!"); |
| } |
| try { |
| DoubleValue set = vm().mirrorOf(1.2345E02); |
| frame.setValue(lv, set); |
| println(" Set: No InvalidTypeException with Double error!"); |
| } catch(com.sun.jdi.InvalidTypeException ex) { |
| println(" Success: Set: InvalidTypeException error has cought as expected!"); |
| } |
| } |
| |
| void checkSetFrameVariables(StackFrame frame) throws Exception { |
| List localVars = frame.visibleVariables(); |
| int index = 0; |
| println("\n Set variable values:"); |
| |
| for (Iterator it = localVars.iterator(); it.hasNext();index++) { |
| LocalVariable lv = (LocalVariable) it.next(); |
| String signature = lv.type().signature(); |
| |
| switch (signature.charAt(0)) { |
| case 'Z': // Boolean Type |
| checkSetBooleanTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'B': // Byte Type |
| checkSetByteTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'C': // Char Type |
| checkSetCharTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'S': // Short Type |
| checkSetShortTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'I': // Integer Type |
| checkSetIntegerTypes(frame, lv); |
| if (index > 0) { // To skip integer method parameter |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| } |
| break; |
| case 'J': // Long Type |
| checkSetLongTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'F': // Float Type |
| checkSetFloatTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeDoubleCheck(frame, lv); |
| break; |
| case 'D': // Double Type |
| checkSetDoubleTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| break; |
| case 'L': |
| if (signature.compareTo("Ljava/lang/String;") == 0) { |
| checkSetStringTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| } |
| if (signature.compareTo("Ljava/lang/Object;") == 0) { |
| checkSetObjectTypes(frame, lv); |
| negativeIntegerCheck(frame, lv); |
| negativeFloatCheck(frame, lv); |
| } |
| break; |
| default: |
| printOneVariable(lv, index); |
| failure(" Failure: List of local variables has a wrong entry!"); |
| }; |
| } |
| } |
| |
| |
| /********** test core **********/ |
| |
| protected void runTests() throws Exception { |
| |
| /* |
| * Get to the top of main() to determine targetClass and mainThread |
| */ |
| BreakpointEvent bpe = startToMain("GetSetLocalTarg"); |
| println("startToMain(GetSetLocalTarg)"); |
| |
| List localVars = printAllVariables("GetSetLocalTarg", "staticMeth"); |
| |
| targetClass = bpe.location().declaringType(); |
| println("targetClass"); |
| |
| mainThread = bpe.thread(); |
| println("mainThread"); |
| |
| EventRequestManager erm = vm().eventRequestManager(); |
| println("EventRequestManager"); |
| StackFrame frame = null; |
| |
| for (int line = START_LINE; line <= STOP_LINE; line += 4) { |
| println("\n resumeTo(GetSetLocalTarg, " + line + ")"); |
| bpe = resumeTo("GetSetLocalTarg", line); |
| frame = bpe.thread().frame(0); |
| printFrameVariables(frame); |
| checkSetFrameVariables(frame); |
| } |
| // Check if we can Get/Set all local vars using last frame state |
| checkGetSetAllVariables(localVars, frame); |
| |
| /* |
| * resume until the end |
| */ |
| listenUntilVMDisconnect(); |
| |
| /* |
| * deal with results of test |
| * if anything has called failure("foo") testFailed will be true |
| */ |
| if (!testFailed) { |
| println("GetSetLocalTest: passed"); |
| } else { |
| throw new Exception("GetSetLocalTest: failed"); |
| } |
| } |
| } |