|
1 /* |
|
2 * Copyright (c) 2005, 2015, 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 6230699 |
|
27 * @summary Test ThreadReference.ownedMonitorsAndFrames() |
|
28 * @bug 6701700 |
|
29 * @summary MonitorInfo objects aren't invalidated when the owning thread is resumed |
|
30 * @author Swamy Venkataramanappa |
|
31 * |
|
32 * @run build TestScaffold VMConnection TargetListener TargetAdapter |
|
33 * @run compile -g MonitorFrameInfo.java |
|
34 * @run driver MonitorFrameInfo |
|
35 */ |
|
36 import com.sun.jdi.*; |
|
37 import com.sun.jdi.event.*; |
|
38 import com.sun.jdi.request.*; |
|
39 |
|
40 import java.util.*; |
|
41 |
|
42 /********** target program **********/ |
|
43 |
|
44 class MonitorTestTarg { |
|
45 static void foo3() { |
|
46 System.out.println("executing foo3"); |
|
47 |
|
48 } |
|
49 static void foo2() { |
|
50 Object l1 = new Object(); |
|
51 synchronized(l1) { |
|
52 System.out.println("executing foo2 " + l1); |
|
53 foo3(); |
|
54 } |
|
55 } |
|
56 static void foo1() { |
|
57 foo2(); |
|
58 } |
|
59 public static void main(String[] args){ |
|
60 System.out.println("Howdy!"); |
|
61 Object l1 = new Object(); |
|
62 synchronized(l1) { |
|
63 System.out.println("executing main" + l1); |
|
64 foo1(); |
|
65 } |
|
66 } |
|
67 } |
|
68 |
|
69 /********** test program **********/ |
|
70 |
|
71 public class MonitorFrameInfo extends TestScaffold { |
|
72 ReferenceType targetClass; |
|
73 ThreadReference mainThread; |
|
74 List monitors; |
|
75 |
|
76 static int expectedCount = 2; |
|
77 static int[] expectedDepth = { 1, 3 }; |
|
78 |
|
79 static String[] expectedNames = {"foo3", "foo2", "foo1", "main"}; |
|
80 |
|
81 MonitorFrameInfo (String args[]) { |
|
82 super(args); |
|
83 } |
|
84 |
|
85 public static void main(String[] args) throws Exception { |
|
86 new MonitorFrameInfo(args).startTests(); |
|
87 } |
|
88 |
|
89 /********** test core **********/ |
|
90 |
|
91 protected void runTests() throws Exception { |
|
92 /* |
|
93 * Get to the top of main() |
|
94 * to determine targetClass and mainThread |
|
95 */ |
|
96 BreakpointEvent bpe = startToMain("MonitorTestTarg"); |
|
97 targetClass = bpe.location().declaringType(); |
|
98 mainThread = bpe.thread(); |
|
99 |
|
100 int initialSize = mainThread.frames().size(); |
|
101 |
|
102 resumeTo("MonitorTestTarg", "foo3", "()V"); |
|
103 |
|
104 if (!mainThread.frame(0).location().method().name() |
|
105 .equals("foo3")) { |
|
106 failure("FAILED: frame failed"); |
|
107 } |
|
108 |
|
109 if (mainThread.frames().size() != (initialSize + 3)) { |
|
110 failure("FAILED: frames size failed"); |
|
111 } |
|
112 |
|
113 if (mainThread.frames().size() != mainThread.frameCount()) { |
|
114 failure("FAILED: frames size not equal to frameCount"); |
|
115 } |
|
116 |
|
117 /* Test monitor frame info. |
|
118 */ |
|
119 if (vm().canGetMonitorFrameInfo()) { |
|
120 System.out.println("Get monitors"); |
|
121 monitors = mainThread.ownedMonitorsAndFrames(); |
|
122 if (monitors.size() != expectedCount) { |
|
123 failure("monitors count is not equal to expected count"); |
|
124 } |
|
125 MonitorInfo mon = null; |
|
126 for (int j=0; j < monitors.size(); j++) { |
|
127 mon = (MonitorInfo)monitors.get(j); |
|
128 System.out.println("Monitor obj " + mon.monitor() + "depth =" +mon.stackDepth()); |
|
129 if (mon.stackDepth() != expectedDepth[j]) { |
|
130 failure("FAILED: monitor stack depth is not equal to expected depth"); |
|
131 } |
|
132 } |
|
133 |
|
134 // The last gotten monInfo is in mon. When we resume the thread, |
|
135 // it should become invalid. We will step out of the top frame |
|
136 // so that the frame depth in this mon object will no longer be correct. |
|
137 // That is why the monInfo's have to become invalid when the thread is |
|
138 // resumed. |
|
139 stepOut(mainThread); |
|
140 boolean ok = false; |
|
141 try { |
|
142 System.out.println("*** Saved Monitor obj " + mon.monitor() + "depth =" +mon.stackDepth()); |
|
143 } catch(InvalidStackFrameException ee) { |
|
144 // ok |
|
145 ok = true; |
|
146 System.out.println("Got expected InvalidStackFrameException after a resume"); |
|
147 } |
|
148 if (!ok) { |
|
149 failure("FAILED: MonitorInfo object was not invalidated by a resume"); |
|
150 } |
|
151 } else { |
|
152 System.out.println("can not get monitors frame info"); |
|
153 } |
|
154 |
|
155 |
|
156 /* |
|
157 * resume until end |
|
158 */ |
|
159 listenUntilVMDisconnect(); |
|
160 |
|
161 /* |
|
162 * deal with results of test |
|
163 * if anything has called failure("foo") testFailed will be true |
|
164 */ |
|
165 if (!testFailed) { |
|
166 println("MonitorFrameInfo: passed"); |
|
167 } else { |
|
168 throw new Exception("MonitorFrameInfo: failed"); |
|
169 } |
|
170 } |
|
171 } |