1 /* 2 * Copyright (c) 2003, 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 package nsk.jvmti.PopFrame; 25 26 import java.io.*; 27 28 /** 29 * This test checks that a method's frame can not be popped by the JVMTI 30 * function <code>PopFrame()</code>: 31 * <li>with intermediate native frames, and a thread, from which 32 * the PopFrame() was called, is different than the current thread 33 * <li>from the current thread with intermediate native frames 34 * <li>no JVMTI events will be generated by the function <code>PopFrame()</code> 35 * 36 * Fixed according to the 4528173 bug: 37 * for now the test checks that a native frame may not be poped. 38 */ 39 public class popframe004 { 40 public static final int PASSED = 0; 41 public static final int FAILED = 2; 42 static final int JCK_STATUS_BASE = 95; 43 44 static volatile boolean popFdone = false; 45 static volatile boolean popF2done = false; 46 static volatile int totRes = PASSED; 47 private PrintStream out; 48 private popFrameCls popFrameClsThr; 49 static Object barrier = new Object(); // for suspending a child thread 50 51 static { 52 try { 53 System.loadLibrary("popframe004"); 54 } catch (UnsatisfiedLinkError e) { 55 System.err.println("Could not load popframe004 library"); 56 System.err.println("java.library.path:" + 57 System.getProperty("java.library.path")); 58 throw e; 59 } 60 } 61 62 native void nativeMeth(popFrameCls popFrameClsThr); 63 native static int doPopFrame(boolean otherThread, Thread popFrameClsThr); 64 native static int getResult(); 65 66 public static void main(String[] argv) { 67 argv = nsk.share.jvmti.JVMTITest.commonInit(argv); 68 69 System.exit(run(argv, System.out) + JCK_STATUS_BASE); 70 } 71 72 public static int run(String argv[], PrintStream out) { 73 return new popframe004().runIt(argv, out); 74 } 75 76 private int runIt(String argv[], PrintStream out) { 77 int retValue = 0; 78 79 this.out = out; 80 81 PipedInputStream pipeIn = new PipedInputStream(); 82 popFrameClsThr = new popFrameCls(pipeIn); 83 synchronized (barrier) { // force a child thread to pause 84 popFrameClsThr.start(); // start a separate thread 85 // wait until the thread will enter into a necessary method 86 try { 87 int _byte = pipeIn.read(); 88 } catch (IOException e) { 89 out.println("TEST FAILED: reading from a pipe: caught " + e); 90 return FAILED; 91 } 92 // pop the frame 93 if (popFrameClsThr.isAlive()) { 94 out.println("Going to pop the frame on other thread..."); 95 retValue = doPopFrame(true, popFrameClsThr); 96 popFdone = true; 97 if (retValue != PASSED) 98 return FAILED; 99 } 100 else { 101 out.println("TEST FAILURE: thread with the method of " + 102 "the popped frame is dead"); 103 return FAILED; 104 } 105 } 106 107 try { 108 if (popFrameClsThr.isAlive()) 109 popFrameClsThr.join(2000); 110 } catch (InterruptedException e) { 111 out.println("TEST INCOMPLETE: caught " + e); 112 totRes = FAILED; 113 } 114 if (popFrameClsThr.isAlive()) { 115 out.println("TEST FAILED: thread with the method of " + 116 "the popped frame is still alive"); 117 totRes = FAILED; 118 } 119 120 out.println("Going to pop the native frame on the current thread..."); 121 totRes = doPopFrame(false, Thread.currentThread()); 122 if (totRes != PASSED) 123 return FAILED; 124 else return getResult(); 125 } 126 127 class popFrameCls extends Thread { 128 private PipedOutputStream pipeOut; 129 130 popFrameCls(PipedInputStream pipeIn) { 131 try { 132 pipeOut = new PipedOutputStream(pipeIn); 133 } catch (IOException e) { 134 out.println("popFrameCls (" + this + 135 "): creating a pipe: caught " + e); 136 return; 137 } 138 } 139 140 public void run() { 141 nativeMeth(popFrameClsThr); 142 out.println("popFrameCls (" + this + "): exiting..."); 143 } 144 145 public void activeMethod() { 146 int retVal = FAILED; 147 boolean compl = true; 148 149 try { 150 out.println("popFrameCls (" + this + "): inside activeMethod()"); 151 pipeOut.write(123); // notify the main thread 152 // pause here until the main thread suspends us 153 synchronized (popframe004.barrier) { 154 while (true) { 155 out.println("popFrameCls (" + this + "): looping..."); 156 if (popframe004.popFdone) { // popping has been done 157 // popping has not to be done due to native frame 158 out.println("popFrameCls (" + this + "): exiting activeMethod()..."); 159 compl = false; 160 return; 161 } 162 } 163 } 164 } catch (Exception e) { 165 out.println("FAILURE: popFrameCls (" + this + "): caught " + e); 166 popframe004.totRes = FAILED; 167 compl = false; 168 } finally { 169 if (compl) { 170 out.println("TEST FAILED: finally block was executed after popping"); 171 popframe004.totRes = FAILED; 172 } 173 } 174 } 175 } 176 }