1 /*
2  * Copyright (c) 2002, 2018, 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 /*
25  * @test
26  * @bug 4511950 4843082
27  * @summary 1. jdb's expression evaluation doesn't perform string conversion properly
28  *          2. TTY: run on expression evaluation
29  * @comment converted from test/jdk/com/sun/jdi/StringConvertTest.sh
30  *
31  * @library /test/lib
32  * @compile -g StringConvertTest.java
33  * @run main/othervm StringConvertTest
34  */
35 
36 import jdk.test.lib.process.OutputAnalyzer;
37 import lib.jdb.JdbCommand;
38 import lib.jdb.JdbTest;
39 
40 class StringConvertTarg {
41     String me;
42     static JJ1 x1;
43     static JJ2 x2;
44     static JJ2[] x3 = new JJ2[2];
45     static String x4 = "abc";
46     static int ii = 89;
47     static String grower = "grower";
48     static StringBuffer sbGrower = new StringBuffer("sbGrower");
49     int ivar = 89;
StringConvertTarg(String xx)50     StringConvertTarg(String xx) {
51         me = xx;
52     }
53 
fred()54     static String fred() {
55         return "a static method";
56     }
57 
gus()58     void  gus() {
59         int gusLoc = 1;
60         StringBuffer sbTim = new StringBuffer("tim");
61         int kk = 1;                          //@1 breakpoint
62     }
63 
growit(String extra)64     static String growit(String extra) {
65         grower += extra;
66         return grower;
67     }
68 
sbGrowit(String extra)69     static String sbGrowit(String extra) {
70         sbGrower.append(extra);
71         return sbGrower.toString();
72     }
73 
main(String[] args)74     public static void main(String[] args) {
75         x1 = new JJ1("first JJ1");
76         x2 = new JJ2("first JJ2");
77         x3[0] = new JJ2("array0");
78         x3[1] = new JJ2("array1");
79         StringConvertTarg loc1 = new StringConvertTarg("first me");
80 
81         // These just show what output should look like
82         System.out.println("x1 = " + x1);
83         System.out.println("x2 = " + x2);
84         System.out.println("x3.toString = " + x3.toString());
85         System.out.println("x4.toString = " + x4.toString());
86 
87         // Dont want to call growit since it would change
88         // the value.
89 
90         System.out.println("loc1 = " + loc1);
91         System.out.println("-" + loc1);
92         loc1.gus();
93      }
94 
95     // This does not have a toString method
96     static class JJ1 {
97         String me;
98 
JJ1(String whoAmI)99         JJ1(String whoAmI) {
100             me = whoAmI;
101         }
102     }
103 
104     // This has a toString method
105     static class JJ2 {
106         String me;
107 
JJ2(String whoAmI)108         JJ2(String whoAmI) {
109             me = whoAmI;
110         }
toString()111         public String toString() {
112             return me;
113         }
114 
meth1()115         public int meth1() {
116             return 89;
117         }
118     }
119 }
120 
121 public class StringConvertTest extends JdbTest {
main(String argv[])122     public static void main(String argv[]) {
123         new StringConvertTest().run();
124     }
125 
StringConvertTest()126     private StringConvertTest() {
127         super(DEBUGGEE_CLASS, SOURCE_FILE);
128     }
129 
130     private static final String DEBUGGEE_CLASS = StringConvertTarg.class.getName();
131     private static final String SOURCE_FILE = "StringConvertTest.java";
132 
133     @Override
runCases()134     protected void runCases() {
135         setBreakpoints(1);
136         // Run to breakpoint #1
137         jdb.command(JdbCommand.run());
138 
139         // Each print without the 'toString()' should print the
140         // same thing as the following print with the toString().
141         // The "print 1"s are just spacers
142         jdb.command(JdbCommand.print("StringConvertTarg.x1"));
143         jdb.command(JdbCommand.print("StringConvertTarg.x1.toString()"));
144         jdb.command(JdbCommand.print("1"));
145 
146         jdb.command(JdbCommand.print("StringConvertTarg.x2"));
147         jdb.command(JdbCommand.print("StringConvertTarg.x2.toString()"));
148         jdb.command(JdbCommand.print("1"));
149 
150         // arrays is a special case.
151         // StringConvertTarg prints:
152         //      x3.toString = [LStringConvertTarg$JJ2;@61443d8f
153         // jdb "print ((Object)StringConvertTarg.x3).toString()" prints:
154         //      com.sun.tools.example.debug.expr.ParseException:
155         //              No instance field or method with the name toString in StringConvertTarg$JJ2[]
156         //      ((Object)StringConvertTarg.x3).toString() = null
157         // jdb "print (Object)(StringConvertTarg.x3)" prints:
158         //      (Object)(StringConvertTarg.x3) = instance of StringConvertTarg$JJ2[2] (id=624)
159         /*
160         jdb.command(JdbCommand.print("(Object)(StringConvertTarg.x3)"));
161         jdb.command(JdbCommand.print("((Object)StringConvertTarg.x3).toString()"));
162         jdb.command(JdbCommand.print("1"));
163         */
164 
165         jdb.command(JdbCommand.print("StringConvertTarg.x4"));
166         jdb.command(JdbCommand.print("StringConvertTarg.x4.toString()"));
167         jdb.command(JdbCommand.print("1"));
168 
169         // Make sure jdb doesn't call a method multiple times.
170         jdb.command(JdbCommand.print("StringConvertTarg.growit(\"xyz\")"));
171         jdb.command(JdbCommand.eval("StringConvertTarg.sbGrower.append(\"xyz\")"));
172         jdb.command(JdbCommand.print("1"));
173 
174         jdb.command(JdbCommand.eval("sbTim.toString()"));
175         jdb.command(JdbCommand.print("1"));
176 
177         jdb.command(JdbCommand.print("this"));
178         jdb.command(JdbCommand.print("this.toString()"));
179         jdb.command(JdbCommand.print("1"));
180 
181         // A possible bug is that this ends up with multiple "s
182         jdb.command(JdbCommand.print("\"--\"StringConvertTarg.x1"));
183         jdb.command(JdbCommand.print("1"));
184 
185         // This too
186         jdb.command(JdbCommand.print("StringConvertTarg.x4 + 2"));
187         jdb.command(JdbCommand.print("1"));
188 
189         jdb.command(JdbCommand.print("this.ivar"));
190         jdb.command(JdbCommand.print("gusLoc"));
191         jdb.command(JdbCommand.print("1"));
192 
193         new OutputAnalyzer(jdb.getJdbOutput())
194                 .shouldNotContain("\"\"")
195                 .shouldNotContain("instance of")
196                 .shouldNotContain("xyzxyz");
197     }
198 }
199