Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineRunningMethodsWithBacktrace.java
41155 views
/*1* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 8087315 801031926* @summary Get old method's stack trace elements after GC27* @requires vm.jvmti28* @library /test/lib29* @modules java.base/jdk.internal.misc30* @modules java.compiler31* java.instrument32* jdk.jartool/sun.tools.jar33* @run main RedefineClassHelper34* @run main/othervm -javaagent:redefineagent.jar RedefineRunningMethodsWithBacktrace35*/3637import static jdk.test.lib.Asserts.*;3839// package access top-level class to avoid problem with RedefineClassHelper40// and nested types.4142class RedefineRunningMethodsWithBacktrace_B {43static int count1 = 0;44static int count2 = 0;45public static volatile boolean stop = false;46static void localSleep() {47try {48Thread.sleep(10);//sleep for 10 ms49} catch(InterruptedException ie) {50}51}5253public static void infinite() {54while (!stop) { count1++; localSleep(); }55}56public static void throwable() {57// add some stuff to the original constant pool58String s1 = new String ("string1");59String s2 = new String ("string2");60String s3 = new String ("string3");61String s4 = new String ("string4");62String s5 = new String ("string5");63String s6 = new String ("string6");64String s7 = new String ("string7");65String s8 = new String ("string8");66String s9 = new String ("string9");67String s10 = new String ("string10");68String s11 = new String ("string11");69String s12 = new String ("string12");70String s13 = new String ("string13");71String s14 = new String ("string14");72String s15 = new String ("string15");73String s16 = new String ("string16");74String s17 = new String ("string17");75String s18 = new String ("string18");76String s19 = new String ("string19");77throw new RuntimeException("throwable called");78}79}8081public class RedefineRunningMethodsWithBacktrace {8283public 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"}";101102public 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"}";118119private static void touchRedefinedMethodInBacktrace(Throwable throwable) {120System.out.println("touchRedefinedMethodInBacktrace: ");121throwable.printStackTrace(); // this actually crashes with the bug in122// java_lang_StackTraceElement::create()123124// Make sure that we can convert the backtrace, which is referring to125// the redefined method, to a StrackTraceElement[] without crashing.126StackTraceElement[] stackTrace = throwable.getStackTrace();127for (int i = 0; i < stackTrace.length; i++) {128StackTraceElement frame = stackTrace[i];129assertNotNull(frame.getClassName(),130"\nTest failed: trace[" + i + "].getClassName() returned null");131assertNotNull(frame.getMethodName(),132"\nTest failed: trace[" + i + "].getMethodName() returned null");133}134}135136private static Throwable getThrowableInB() {137Throwable t = null;138try {139RedefineRunningMethodsWithBacktrace_B.throwable();140} catch (Exception e) {141t = e;142// Don't print here because Throwable will cache the constructed stacktrace143// e.printStackTrace();144}145return t;146}147148149public static void main(String[] args) throws Exception {150151new Thread() {152public void run() {153RedefineRunningMethodsWithBacktrace_B.infinite();154}155}.start();156157Throwable t1 = getThrowableInB();158159RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, newB);160161System.gc();162163Throwable t2 = getThrowableInB();164165RedefineRunningMethodsWithBacktrace_B.infinite();166167for (int i = 0; i < 20 ; i++) {168String s = new String("some garbage");169System.gc();170}171172RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, evenNewerB);173System.gc();174175Throwable t3 = getThrowableInB();176177for (int i = 0; i < 20 ; i++) {178RedefineRunningMethodsWithBacktrace_B.infinite();179String s = new String("some garbage");180System.gc();181}182183touchRedefinedMethodInBacktrace(t1);184touchRedefinedMethodInBacktrace(t2);185touchRedefinedMethodInBacktrace(t3);186187// purge should clean everything up.188RedefineRunningMethodsWithBacktrace_B.stop = true;189190for (int i = 0; i < 20 ; i++) {191RedefineRunningMethodsWithBacktrace_B.infinite();192String s = new String("some garbage");193System.gc();194}195}196}197198199