blob: a14a63e3491fabd4db684c89813d9a0eaaa261b5 [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
alanb0d058232012-11-02 15:50:11 +00002 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
duke6e45e102007-12-01 00:00:00 +00003 * 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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * 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.
duke6e45e102007-12-01 00:00:00 +000022 */
23
24/**
25 * @test
26 * @bug 4409241 4432820
27 * @summary Test the bug fix for: MethodExitEvents disappear when Object-Methods are called from main
28 * @author Tim Bell
29 *
30 * @run build TestScaffold VMConnection TargetListener TargetAdapter
31 * @run compile -g MethodEntryExitEvents.java
32 * @run main MethodEntryExitEvents SUSPEND_EVENT_THREAD MethodEntryExitEventsDebugee
33 * @run main MethodEntryExitEvents SUSPEND_NONE MethodEntryExitEventsDebugee
34 * @run main MethodEntryExitEvents SUSPEND_ALL MethodEntryExitEventsDebugee
35 */
36import com.sun.jdi.*;
37import com.sun.jdi.event.*;
38import com.sun.jdi.request.*;
39import java.util.*;
40
41class t2 {
42 public static void sayHello1(int i, int j) {
43 sayHello2(i, j);
44 }
45 public static void sayHello2(int i, int j) {
46 sayHello3(i, j);
47 }
48 public static void sayHello3(int i, int j) {
49 sayHello4(i, j);
50 }
51 public static void sayHello4(int i, int j) {
52 sayHello5(i, j);
53 }
54 public static void sayHello5(int i, int j) {
55 if (i < 2) {
56 sayHello1(++i, j);
57 } else {
58 System.out.print ("MethodEntryExitEventsDebugee: ");
59 System.out.print (" -->> Hello. j is: ");
60 System.out.print (j);
61 System.out.println(" <<--");
62 }
63 }
64}
65
66class MethodEntryExitEventsDebugee {
67 public static void loopComplete () {
68 /*
69 * The implementation here is deliberately inefficient
70 * because the debugger is still watching this method.
71 */
72 StringBuffer sb = new StringBuffer();
73 sb.append ("MethodEntryExitEventsDebugee: ");
74 sb.append ("Executing loopComplete method for a graceful shutdown...");
75 String s = sb.toString();
76 for (int i = 0; i < s.length(); i++) {
77 char c = s.charAt(i);
78 System.out.print(c);
79 }
80 System.out.println();
81 }
82 public static void main(String[] args) {
83 t2 test = new t2();
84 for (int j = 0; j < 3; j++) {
85 test.sayHello1(0, j);
86 }
87 loopComplete();
88 }
89}
90
91
92public class MethodEntryExitEvents extends TestScaffold {
93 int sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
94 StepRequest stepReq = null; //Only one step request allowed per thread
95 boolean finishedCounting = false;
96
97 /*
98 * Enter main() , then t2.<init>, then sayHello[1,2,3,4,5] 15 times 3 loops,
99 * then loopComplete()
100 */
101 final int expectedEntryCount = 1 + 1 + (15 * 3) + 1;
102 int methodEntryCount = 0;
103
104 /*
105 * Exit t2.<init>, then sayHello[1,2,3,4,5] 15 times 3 loopa
106 * (event monitoring is cancelled before we exit loopComplete() or main())
107 */
108 final int expectedExitCount = 1 + (15 * 3);
109 int methodExitCount = 0;
110
111 /*
112 * Class patterns for which we don't want events (copied
113 * from the "Trace.java" example):
114 * http://java.sun.com/javase/technologies/core/toolsapis/jpda/
115 */
116 private String[] excludes = {"java.*", "javax.*", "sun.*",
rbackman5272e2e2012-03-14 08:43:28 +0100117 "com.sun.*", "com.oracle.*",
slaff734422013-09-20 10:15:02 +0200118 "oracle.*", "jdk.internal.*"};
duke6e45e102007-12-01 00:00:00 +0000119
120 MethodEntryExitEvents (String args[]) {
121 super(args);
122 }
123
124 private void usage(String[] args) throws Exception {
125 StringBuffer sb = new StringBuffer("Usage: ");
126 sb.append(System.getProperty("line.separator"));
127 sb.append(" java ");
128 sb.append(getClass().getName());
129 sb.append(" [SUSPEND_NONE | SUSPEND_EVENT_THREAD | SUSPEND_ALL]");
130 sb.append(" [MethodEntryExitEventsDebugee | -connect <connector options...>] ");
131 throw new Exception (sb.toString());
132 }
133
134 public static void main(String[] args) throws Exception {
135 MethodEntryExitEvents meee = new MethodEntryExitEvents (args);
136 meee.startTests();
137 }
138
139 public void exceptionThrown(ExceptionEvent event) {
140 System.out.println("Exception: " + event.exception());
141 System.out.println(" at catch location: " + event.catchLocation());
142
143 // Step to the catch
144 if (stepReq == null) {
145 stepReq =
146 eventRequestManager().createStepRequest(event.thread(),
147 StepRequest.STEP_MIN,
148 StepRequest.STEP_INTO);
149 stepReq.addCountFilter(1); // next step only
150 stepReq.setSuspendPolicy(EventRequest.SUSPEND_ALL);
151 }
152 stepReq.enable();
153 }
154 public void stepCompleted(StepEvent event) {
155 System.out.println("stepCompleted: line#=" +
156 event.location().lineNumber() +
157 " event=" + event);
158 // disable the step and then run to completion
159 //eventRequestManager().deleteEventRequest(event.request());
160 StepRequest str= (StepRequest)event.request();
161 str.disable();
162 }
163 public void methodEntered(MethodEntryEvent event) {
164 if (! finishedCounting) {
165 // We have to count the entry to loopComplete, but
166 // not the exit
167 methodEntryCount++;
168 System.out.print (" Method entry number: ");
169 System.out.print (methodEntryCount);
170 System.out.print (" : ");
171 System.out.println(event);
172 if ("loopComplete".equals(event.method().name())) {
173 finishedCounting = true;
174 }
175 }
176 }
177
178 public void methodExited(MethodExitEvent event) {
179 if (! finishedCounting){
180 methodExitCount++;
181 System.out.print (" Method exit number: ");
182 System.out.print (methodExitCount);
183 System.out.print (" : ");
184 System.out.println(event);
185 }
186 }
187
188 protected void runTests() throws Exception {
189 if (args.length < 1) {
190 usage(args);
191 }
192 //Pick up the SUSPEND_xxx in first argument
193 if ("SUSPEND_NONE".equals(args[0])) {
194 sessionSuspendPolicy = EventRequest.SUSPEND_NONE;
195 } else if ("SUSPEND_EVENT_THREAD".equals(args[0])) {
196 sessionSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
197 } else if ("SUSPEND_ALL".equals(args[0])) {
198 sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
199 } else {
200 usage(args);
201 }
202 System.out.print("Suspend policy is: ");
203 System.out.println(args[0]);
204
205 // Skip the test arg
206 String[] args2 = new String[args.length - 1];
207 System.arraycopy(args, 1, args2, 0, args.length - 1);
208
209 if (args2.length < 1) {
210 usage(args2);
211 }
212 List argList = new ArrayList(Arrays.asList(args2));
213 System.out.println("run args: " + argList);
214 connect((String[]) argList.toArray(args2));
215 waitForVMStart();
216
217 try {
218
219 /*
220 * Ask for Exception events
221 */
222 ExceptionRequest exceptionRequest =
223 eventRequestManager().createExceptionRequest(null, // refType (null == all instances)
224 true, // notifyCaught
225 true);// notifyUncaught
226 exceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
227 exceptionRequest.enable();
228
229 /*
230 * Ask for method entry events
231 */
232 MethodEntryRequest entryRequest =
233 eventRequestManager().createMethodEntryRequest();
234 for (int i=0; i<excludes.length; ++i) {
235 entryRequest.addClassExclusionFilter(excludes[i]);
236 }
237 entryRequest.setSuspendPolicy(sessionSuspendPolicy);
238 entryRequest.enable();
239
240 /*
241 * Ask for method exit events
242 */
243 MethodExitRequest exitRequest =
244 eventRequestManager().createMethodExitRequest();
245
246 for (int i=0; i<excludes.length; ++i) {
247 exitRequest.addClassExclusionFilter(excludes[i]);
248 }
249 exitRequest.setSuspendPolicy(sessionSuspendPolicy);
250 exitRequest.enable();
251
252 /*
253 * We are now set up to receive the notifications we want.
254 * Here we go. This adds 'this' as a listener so
255 * that our handlers above will be called.
256 */
257
258 listenUntilVMDisconnect();
259 System.out.println("All done...");
260
261 } catch (Exception ex){
262 ex.printStackTrace();
263 testFailed = true;
264 }
265
266 if ((methodEntryCount != expectedEntryCount) ||
267 (methodExitCount != expectedExitCount)) {
268 testFailed = true;
269 }
270 if (!testFailed) {
271 System.out.println();
272 System.out.println("MethodEntryExitEvents: passed");
273 System.out.print (" Method entry count: ");
274 System.out.println(methodEntryCount);
275 System.out.print (" Method exit count: ");
276 System.out.println(methodExitCount);
277 } else {
278 System.out.println();
279 System.out.println("MethodEntryExitEvents: failed");
280 System.out.print (" expected method entry count: ");
281 System.out.println(expectedEntryCount);
282 System.out.print (" observed method entry count: ");
283 System.out.println(methodEntryCount);
284 System.out.print (" expected method exit count: ");
285 System.out.println(expectedExitCount);
286 System.out.print (" observed method exit count: ");
287 System.out.println(methodExitCount);
288 throw new Exception("MethodEntryExitEvents: failed");
289 }
290 }
291}