1 /*
2  * Copyright (c) 2007, 2020, 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  *
27  * @summary converted from VM Testbase nsk/jvmti/scenarios/hotswap/HS203/hs203t003.
28  * VM Testbase keywords: [quick, jpda, jvmti, onload_only_caps, noras, redefine, feature_hotswap]
29  * VM Testbase readme:
30  * Description ::
31  *     Redefining a class while its field is being accessed, pop currently executing frame
32  *     (return back to method call statement) and resume its execution.
33  *     The Test creates a Thread (MyThread). During class is being prepared,
34  *     a  field watch is added to jvmti. The thread is allowed to run (execute).
35  *     During field change callbacks, class is being redefined with to (./newclass/MyThread.java)
36  *     a different version of class and suspended's thread. The main thread would pop frame
37  *     and resume its execution.
38  *     The test is expected to pass, if redefine class is effective after resuming thread.
39  *     (Hint : A thread `s frame can be poped only if it is suspended, so we need to suspend,
40  *     later resume that thread).
41  *
42  * @library /vmTestbase
43  *          /test/lib
44  * @build nsk.jvmti.scenarios.hotswap.HS203.hs203t003.hs203t003
45  *
46  * @comment compile newclassXX to bin/newclassXX
47  * @run driver nsk.share.ExtraClassesBuilder
48  *      newclass00
49  *
50  * @build ExecDriver
51  * @run main/othervm/native PropertyResolvingWrapper ExecDriver --java
52  *      "-agentlib:hs203t003=pathToNewByteCode=./bin -waittime=5 package=nsk samples=100 mode=compiled"
53  *      nsk.jvmti.scenarios.hotswap.HS203.hs203t003.hs203t003
54  */
55 
56 package nsk.jvmti.scenarios.hotswap.HS203.hs203t003;
57 
58 import nsk.share.jvmti.RedefineAgent;
59 import java.util.concurrent.atomic.AtomicBoolean;
60 
61 public class hs203t003 extends RedefineAgent {
62 
popThreadFrame(Thread thread)63     public native boolean popThreadFrame(Thread thread);
isSuspended(Thread thread)64     public native boolean isSuspended(Thread thread);
resumeThread(Thread thread)65     public native boolean resumeThread(Thread thread);
66 
67 
hs203t003(String[] arg)68     public hs203t003(String[] arg) {
69         super(arg);
70     }
71 
main(String[] arg)72     public static void main(String[] arg) {
73         arg = nsk.share.jvmti.JVMTITest.commonInit(arg);
74 
75         hs203t003 hsCase = new hs203t003(arg);
76         System.exit(hsCase.runAgent());
77     }
78 
79 
agentMethod()80     public boolean agentMethod() {
81         boolean passed = false;
82         MyThread mt = new MyThread();
83         try {
84             mt.start();
85             // Check if we can can pop the thread.
86             // We can not do redefine/pop frame on run method.
87             while (!MyThread.resume.get());
88             // Sleep for some few secs to get redefined.
89             while (!isRedefined()) {
90                 if (!agentStatus()) {
91                     System.out.println("Failed to redefine class");
92                     return passed;
93                 }
94                 Thread.sleep(100);
95             }
96             // Wait for the thread to be suspended.
97             while (!isSuspended(mt)) {
98                 if (!agentStatus()) {
99                     System.out.println("Failed to suspend thread");
100                     return passed;
101                 }
102                 Thread.sleep(100);
103             }
104             // Pop the frame.
105             if (!popThreadFrame(mt)) {
106                 System.out.println("Failed to pop a frame = "
107                                    + mt.threadState);
108             }
109             // Resume the thread.
110             if(!resumeThread(mt)) {
111                 System.out.println("Failed to resume the thread = "
112                                    + mt.threadState);
113             }
114             // Wait till the other thread completes its execution.
115             mt.join();
116             System.out.println("Thread state after popping/redefining = "
117                                + mt.threadState);
118         } catch(Exception ie) {
119             ie.printStackTrace();
120         }
121         if ((mt.threadState < 1000) && agentStatus()) {
122             passed = true;
123         }
124         return passed;
125     }
126 
127 }
128