1 /*
2 * Copyright (c) 2015, 2016, 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 8087315
27 * @summary Get old method's stack trace elements after GC
28 * @library /test/lib
29 * @modules java.base/jdk.internal.misc
30 * @modules java.compiler
31 * java.instrument
32 * jdk.jartool/sun.tools.jar
33 * @run main RedefineClassHelper
34 * @run main/othervm -javaagent:redefineagent.jar RedefineRunningMethodsWithBacktrace
35 */
36
37 import static jdk.test.lib.Asserts.*;
38
39 public class RedefineRunningMethodsWithBacktrace {
40
41 public static String newB =
42 "class RedefineRunningMethodsWithBacktrace$B {" +
43 " static int count1 = 0;" +
44 " static int count2 = 0;" +
45 " public static volatile boolean stop = false;" +
46 " static void localSleep() { " +
47 " try{ " +
48 " Thread.currentThread().sleep(10);" +
49 " } catch(InterruptedException ie) { " +
50 " } " +
51 " } " +
52 " public static void infinite() { " +
53 " System.out.println(\"infinite called\");" +
54 " }" +
55 " public static void throwable() { " +
56 " throw new RuntimeException(\"throwable called\");" +
57 " }" +
58 "}";
59
60 public static String evenNewerB =
61 "class RedefineRunningMethodsWithBacktrace$B {" +
62 " static int count1 = 0;" +
63 " static int count2 = 0;" +
64 " public static volatile boolean stop = false;" +
65 " static void localSleep() { " +
66 " try{ " +
67 " Thread.currentThread().sleep(1);" +
68 " } catch(InterruptedException ie) { " +
69 " } " +
70 " } " +
71 " public static void infinite() { }" +
72 " public static void throwable() { " +
73 " throw new RuntimeException(\"throwable called\");" +
74 " }" +
75 "}";
76
77 static class B {
78 static int count1 = 0;
79 static int count2 = 0;
80 public static volatile boolean stop = false;
81 static void localSleep() {
82 try {
83 Thread.currentThread().sleep(10);//sleep for 10 ms
84 } catch(InterruptedException ie) {
85 }
86 }
87
88 public static void infinite() {
89 while (!stop) { count1++; localSleep(); }
90 }
91 public static void throwable() {
92 // add some stuff to the original constant pool
93 String s1 = new String ("string1");
94 String s2 = new String ("string2");
95 String s3 = new String ("string3");
96 String s4 = new String ("string4");
97 String s5 = new String ("string5");
98 String s6 = new String ("string6");
99 String s7 = new String ("string7");
100 String s8 = new String ("string8");
101 String s9 = new String ("string9");
102 String s10 = new String ("string10");
103 String s11 = new String ("string11");
104 String s12 = new String ("string12");
105 String s13 = new String ("string13");
106 String s14 = new String ("string14");
107 String s15 = new String ("string15");
108 String s16 = new String ("string16");
109 String s17 = new String ("string17");
110 String s18 = new String ("string18");
111 String s19 = new String ("string19");
112 throw new RuntimeException("throwable called");
113 }
114 }
115
116 private static void touchRedefinedMethodInBacktrace(Throwable throwable) {
117 System.out.println("touchRedefinedMethodInBacktrace: ");
118 throwable.printStackTrace(); // this actually crashes with the bug in
119 // java_lang_StackTraceElement::create()
120
121 // Make sure that we can convert the backtrace, which is referring to
122 // the redefined method, to a StrackTraceElement[] without crashing.
123 StackTraceElement[] stackTrace = throwable.getStackTrace();
124 for (int i = 0; i < stackTrace.length; i++) {
125 StackTraceElement frame = stackTrace[i];
126 assertNotNull(frame.getClassName(),
127 "\nTest failed: trace[" + i + "].getClassName() returned null");
128 assertNotNull(frame.getMethodName(),
129 "\nTest failed: trace[" + i + "].getMethodName() returned null");
130 }
131 }
132
133 private static Throwable getThrowableInB() {
134 Throwable t = null;
135 try {
136 B.throwable();
137 } catch (Exception e) {
138 t = e;
139 // Don't print here because Throwable will cache the constructed stacktrace
140 // e.printStackTrace();
141 }
142 return t;
143 }
144
145
146 public static void main(String[] args) throws Exception {
147
148 new Thread() {
149 public void run() {
150 B.infinite();
151 }
152 }.start();
153
154 Throwable t1 = getThrowableInB();
155
156 RedefineClassHelper.redefineClass(B.class, newB);
157
158 System.gc();
159
160 Throwable t2 = getThrowableInB();
161
162 B.infinite();
163
164 for (int i = 0; i < 20 ; i++) {
165 String s = new String("some garbage");
166 System.gc();
167 }
168
169 RedefineClassHelper.redefineClass(B.class, evenNewerB);
170 System.gc();
171
172 Throwable t3 = getThrowableInB();
173
174 for (int i = 0; i < 20 ; i++) {
175 B.infinite();
176 String s = new String("some garbage");
177 System.gc();
178 }
179
180 touchRedefinedMethodInBacktrace(t1);
181 touchRedefinedMethodInBacktrace(t2);
182 touchRedefinedMethodInBacktrace(t3);
183
184 // purge should clean everything up.
185 B.stop = true;
186
187 for (int i = 0; i < 20 ; i++) {
188 B.infinite();
189 String s = new String("some garbage");
190 System.gc();
191 }
192 }
193 }
|
1 /*
2 * Copyright (c) 2015, 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 8087315 8010319
27 * @summary Get old method's stack trace elements after GC
28 * @library /test/lib
29 * @modules java.base/jdk.internal.misc
30 * @modules java.compiler
31 * java.instrument
32 * jdk.jartool/sun.tools.jar
33 * @run main RedefineClassHelper
34 * @run main/othervm -javaagent:redefineagent.jar RedefineRunningMethodsWithBacktrace
35 */
36
37 import static jdk.test.lib.Asserts.*;
38
39 // package access top-level class to avoid problem with RedefineClassHelper
40 // and nested types.
41
42 class RedefineRunningMethodsWithBacktrace_B {
43 static int count1 = 0;
44 static int count2 = 0;
45 public static volatile boolean stop = false;
46 static void localSleep() {
47 try {
48 Thread.sleep(10);//sleep for 10 ms
49 } catch(InterruptedException ie) {
50 }
51 }
52
53 public static void infinite() {
54 while (!stop) { count1++; localSleep(); }
55 }
56 public static void throwable() {
57 // add some stuff to the original constant pool
58 String s1 = new String ("string1");
59 String s2 = new String ("string2");
60 String s3 = new String ("string3");
61 String s4 = new String ("string4");
62 String s5 = new String ("string5");
63 String s6 = new String ("string6");
64 String s7 = new String ("string7");
65 String s8 = new String ("string8");
66 String s9 = new String ("string9");
67 String s10 = new String ("string10");
68 String s11 = new String ("string11");
69 String s12 = new String ("string12");
70 String s13 = new String ("string13");
71 String s14 = new String ("string14");
72 String s15 = new String ("string15");
73 String s16 = new String ("string16");
74 String s17 = new String ("string17");
75 String s18 = new String ("string18");
76 String s19 = new String ("string19");
77 throw new RuntimeException("throwable called");
78 }
79 }
80
81 public class RedefineRunningMethodsWithBacktrace {
82
83 public static String newB =
84 "class RedefineRunningMethodsWithBacktrace_B {" +
85 " static int count1 = 0;" +
86 " static int count2 = 0;" +
87 " public static volatile boolean stop = false;" +
88 " static void localSleep() { " +
89 " try{ " +
90 " Thread.sleep(10);" +
91 " } catch(InterruptedException ie) { " +
92 " } " +
93 " } " +
94 " public static void infinite() { " +
95 " System.out.println(\"infinite called\");" +
96 " }" +
97 " public static void throwable() { " +
98 " throw new RuntimeException(\"throwable called\");" +
99 " }" +
100 "}";
101
102 public static String evenNewerB =
103 "class RedefineRunningMethodsWithBacktrace_B {" +
104 " static int count1 = 0;" +
105 " static int count2 = 0;" +
106 " public static volatile boolean stop = false;" +
107 " static void localSleep() { " +
108 " try{ " +
109 " Thread.sleep(1);" +
110 " } catch(InterruptedException ie) { " +
111 " } " +
112 " } " +
113 " public static void infinite() { }" +
114 " public static void throwable() { " +
115 " throw new RuntimeException(\"throwable called\");" +
116 " }" +
117 "}";
118
119 private static void touchRedefinedMethodInBacktrace(Throwable throwable) {
120 System.out.println("touchRedefinedMethodInBacktrace: ");
121 throwable.printStackTrace(); // this actually crashes with the bug in
122 // java_lang_StackTraceElement::create()
123
124 // Make sure that we can convert the backtrace, which is referring to
125 // the redefined method, to a StrackTraceElement[] without crashing.
126 StackTraceElement[] stackTrace = throwable.getStackTrace();
127 for (int i = 0; i < stackTrace.length; i++) {
128 StackTraceElement frame = stackTrace[i];
129 assertNotNull(frame.getClassName(),
130 "\nTest failed: trace[" + i + "].getClassName() returned null");
131 assertNotNull(frame.getMethodName(),
132 "\nTest failed: trace[" + i + "].getMethodName() returned null");
133 }
134 }
135
136 private static Throwable getThrowableInB() {
137 Throwable t = null;
138 try {
139 RedefineRunningMethodsWithBacktrace_B.throwable();
140 } catch (Exception e) {
141 t = e;
142 // Don't print here because Throwable will cache the constructed stacktrace
143 // e.printStackTrace();
144 }
145 return t;
146 }
147
148
149 public static void main(String[] args) throws Exception {
150
151 new Thread() {
152 public void run() {
153 RedefineRunningMethodsWithBacktrace_B.infinite();
154 }
155 }.start();
156
157 Throwable t1 = getThrowableInB();
158
159 RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, newB);
160
161 System.gc();
162
163 Throwable t2 = getThrowableInB();
164
165 RedefineRunningMethodsWithBacktrace_B.infinite();
166
167 for (int i = 0; i < 20 ; i++) {
168 String s = new String("some garbage");
169 System.gc();
170 }
171
172 RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, evenNewerB);
173 System.gc();
174
175 Throwable t3 = getThrowableInB();
176
177 for (int i = 0; i < 20 ; i++) {
178 RedefineRunningMethodsWithBacktrace_B.infinite();
179 String s = new String("some garbage");
180 System.gc();
181 }
182
183 touchRedefinedMethodInBacktrace(t1);
184 touchRedefinedMethodInBacktrace(t2);
185 touchRedefinedMethodInBacktrace(t3);
186
187 // purge should clean everything up.
188 RedefineRunningMethodsWithBacktrace_B.stop = true;
189
190 for (int i = 0; i < 20 ; i++) {
191 RedefineRunningMethodsWithBacktrace_B.infinite();
192 String s = new String("some garbage");
193 System.gc();
194 }
195 }
196 }
|