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  */
36 import com.sun.jdi.*;
37 import com.sun.jdi.event.*;
38 import com.sun.jdi.request.*;
39 
40 import java.util.*;
41 
42     /********** target program **********/
43 
44 class GetSetLocalTarg {
main(String[] args)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      */
staticMeth(int intArg)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 
151 public 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 
GetSetLocalTest(String args[])157     GetSetLocalTest (String args[]) {
158         super(args);
159     }
160 
main(String[] args)161     public static void main(String[] args) throws Exception {
162         new GetSetLocalTest(args).startTests();
163     }
164 
165     /********** test assist **********/
166 
getMethod(String className, String methodName)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 
printAllVariables(String className, String methodName)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 
checkGetSetAllVariables(List localVars, StackFrame frame)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 
printOneVariable(LocalVariable lv, int index)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 
printFrameVariables(StackFrame frame)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 
incrValue(BooleanValue val)255     BooleanValue incrValue(BooleanValue val) {
256         boolean value = val.value();
257         return vm().mirrorOf(!value);
258     }
259 
incrValue(ByteValue val)260     ByteValue incrValue(ByteValue val) {
261         byte value = val.value();
262         return vm().mirrorOf(++value);
263     }
264 
incrValue(CharValue val)265     CharValue incrValue(CharValue val) {
266         char value = val.value();
267         return vm().mirrorOf(++value);
268     }
269 
incrValue(ShortValue val)270     ShortValue incrValue(ShortValue val) {
271         short value = val.value();
272         return vm().mirrorOf(++value);
273     }
274 
incrValue(IntegerValue val)275     IntegerValue incrValue(IntegerValue val) {
276         int value = val.value();
277         return vm().mirrorOf(++value);
278     }
279 
incrValue(LongValue val)280     LongValue incrValue(LongValue val) {
281         long value = val.value();
282         return vm().mirrorOf(++value);
283     }
284 
incrValue(FloatValue val)285     FloatValue incrValue(FloatValue val) {
286         float value = val.value();
287         return  vm().mirrorOf(++value);
288     }
289 
incrValue(DoubleValue val)290     DoubleValue incrValue(DoubleValue val) {
291         double value = val.value();
292         return vm().mirrorOf(++value);
293     }
294 
incrValue(StringReference val)295     StringReference incrValue(StringReference val) {
296         String newstr = new String("Set String ").concat(val.value());
297         return vm().mirrorOf(newstr);
298     }
299 
checkSetBooleanTypes(StackFrame frame, LocalVariable lv)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 
checkSetByteTypes(StackFrame frame, LocalVariable lv)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 
checkSetCharTypes(StackFrame frame, LocalVariable lv)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 
checkSetShortTypes(StackFrame frame, LocalVariable lv)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 
checkSetIntegerTypes(StackFrame frame, LocalVariable lv)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 
checkSetLongTypes(StackFrame frame, LocalVariable lv)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 
checkSetFloatTypes(StackFrame frame, LocalVariable lv)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 
checkSetDoubleTypes(StackFrame frame, LocalVariable lv)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 
checkSetStringTypes(StackFrame frame, LocalVariable lv)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 
checkSetObjectTypes(StackFrame frame, LocalVariable lv)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 
negativeIntegerCheck(StackFrame frame, LocalVariable lv)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 
negativeFloatCheck(StackFrame frame, LocalVariable lv)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 
negativeDoubleCheck(StackFrame frame, LocalVariable lv)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 
checkSetFrameVariables(StackFrame frame)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 
runTests()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