/* * 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"); } } }