blob: e5b8b82319b08685fc43c30c21399c0c4ac4681c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
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.*",
117 "com.sun.*"};
118
119 MethodEntryExitEvents (String args[]) {
120 super(args);
121 }
122
123 private void usage(String[] args) throws Exception {
124 StringBuffer sb = new StringBuffer("Usage: ");
125 sb.append(System.getProperty("line.separator"));
126 sb.append(" java ");
127 sb.append(getClass().getName());
128 sb.append(" [SUSPEND_NONE | SUSPEND_EVENT_THREAD | SUSPEND_ALL]");
129 sb.append(" [MethodEntryExitEventsDebugee | -connect <connector options...>] ");
130 throw new Exception (sb.toString());
131 }
132
133 public static void main(String[] args) throws Exception {
134 MethodEntryExitEvents meee = new MethodEntryExitEvents (args);
135 meee.startTests();
136 }
137
138 public void exceptionThrown(ExceptionEvent event) {
139 System.out.println("Exception: " + event.exception());
140 System.out.println(" at catch location: " + event.catchLocation());
141
142 // Step to the catch
143 if (stepReq == null) {
144 stepReq =
145 eventRequestManager().createStepRequest(event.thread(),
146 StepRequest.STEP_MIN,
147 StepRequest.STEP_INTO);
148 stepReq.addCountFilter(1); // next step only
149 stepReq.setSuspendPolicy(EventRequest.SUSPEND_ALL);
150 }
151 stepReq.enable();
152 }
153 public void stepCompleted(StepEvent event) {
154 System.out.println("stepCompleted: line#=" +
155 event.location().lineNumber() +
156 " event=" + event);
157 // disable the step and then run to completion
158 //eventRequestManager().deleteEventRequest(event.request());
159 StepRequest str= (StepRequest)event.request();
160 str.disable();
161 }
162 public void methodEntered(MethodEntryEvent event) {
163 if (! finishedCounting) {
164 // We have to count the entry to loopComplete, but
165 // not the exit
166 methodEntryCount++;
167 System.out.print (" Method entry number: ");
168 System.out.print (methodEntryCount);
169 System.out.print (" : ");
170 System.out.println(event);
171 if ("loopComplete".equals(event.method().name())) {
172 finishedCounting = true;
173 }
174 }
175 }
176
177 public void methodExited(MethodExitEvent event) {
178 if (! finishedCounting){
179 methodExitCount++;
180 System.out.print (" Method exit number: ");
181 System.out.print (methodExitCount);
182 System.out.print (" : ");
183 System.out.println(event);
184 }
185 }
186
187 protected void runTests() throws Exception {
188 if (args.length < 1) {
189 usage(args);
190 }
191 //Pick up the SUSPEND_xxx in first argument
192 if ("SUSPEND_NONE".equals(args[0])) {
193 sessionSuspendPolicy = EventRequest.SUSPEND_NONE;
194 } else if ("SUSPEND_EVENT_THREAD".equals(args[0])) {
195 sessionSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
196 } else if ("SUSPEND_ALL".equals(args[0])) {
197 sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
198 } else {
199 usage(args);
200 }
201 System.out.print("Suspend policy is: ");
202 System.out.println(args[0]);
203
204 // Skip the test arg
205 String[] args2 = new String[args.length - 1];
206 System.arraycopy(args, 1, args2, 0, args.length - 1);
207
208 if (args2.length < 1) {
209 usage(args2);
210 }
211 List argList = new ArrayList(Arrays.asList(args2));
212 System.out.println("run args: " + argList);
213 connect((String[]) argList.toArray(args2));
214 waitForVMStart();
215
216 try {
217
218 /*
219 * Ask for Exception events
220 */
221 ExceptionRequest exceptionRequest =
222 eventRequestManager().createExceptionRequest(null, // refType (null == all instances)
223 true, // notifyCaught
224 true);// notifyUncaught
225 exceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
226 exceptionRequest.enable();
227
228 /*
229 * Ask for method entry events
230 */
231 MethodEntryRequest entryRequest =
232 eventRequestManager().createMethodEntryRequest();
233 for (int i=0; i<excludes.length; ++i) {
234 entryRequest.addClassExclusionFilter(excludes[i]);
235 }
236 entryRequest.setSuspendPolicy(sessionSuspendPolicy);
237 entryRequest.enable();
238
239 /*
240 * Ask for method exit events
241 */
242 MethodExitRequest exitRequest =
243 eventRequestManager().createMethodExitRequest();
244
245 for (int i=0; i<excludes.length; ++i) {
246 exitRequest.addClassExclusionFilter(excludes[i]);
247 }
248 exitRequest.setSuspendPolicy(sessionSuspendPolicy);
249 exitRequest.enable();
250
251 /*
252 * We are now set up to receive the notifications we want.
253 * Here we go. This adds 'this' as a listener so
254 * that our handlers above will be called.
255 */
256
257 listenUntilVMDisconnect();
258 System.out.println("All done...");
259
260 } catch (Exception ex){
261 ex.printStackTrace();
262 testFailed = true;
263 }
264
265 if ((methodEntryCount != expectedEntryCount) ||
266 (methodExitCount != expectedExitCount)) {
267 testFailed = true;
268 }
269 if (!testFailed) {
270 System.out.println();
271 System.out.println("MethodEntryExitEvents: passed");
272 System.out.print (" Method entry count: ");
273 System.out.println(methodEntryCount);
274 System.out.print (" Method exit count: ");
275 System.out.println(methodExitCount);
276 } else {
277 System.out.println();
278 System.out.println("MethodEntryExitEvents: failed");
279 System.out.print (" expected method entry count: ");
280 System.out.println(expectedEntryCount);
281 System.out.print (" observed method entry count: ");
282 System.out.println(methodEntryCount);
283 System.out.print (" expected method exit count: ");
284 System.out.println(expectedExitCount);
285 System.out.print (" observed method exit count: ");
286 System.out.println(methodExitCount);
287 throw new Exception("MethodEntryExitEvents: failed");
288 }
289 }
290}