blob: a1c9abc2a2e25e4fef267ca2cdfd6d8d80552c81 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001-2002 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 4467564
27 * @summary Test the popping of frames in an asynchronous context
28 * (that is, when suspended by the debugger at random points)
29 *
30 * @author Robert Field
31 *
32 * @run build TestScaffold VMConnection TargetListener TargetAdapter
33 * @run compile -g PopAsynchronousTest.java
34 * @run main PopAsynchronousTest
35 */
36import com.sun.jdi.*;
37import com.sun.jdi.event.*;
38import com.sun.jdi.request.*;
39
40import java.util.*;
41
42 /********** target program **********/
43
44class PopAsynchronousTarg {
45 static final int N = 30;
46 int fibonacci(int n) {
47 if (n <= 2) {
48 return 1;
49 } else {
50 return fibonacci(n-1) + fibonacci(n-2);
51 }
52 }
53 void report(int n, int result) {
54 System.out.println("fibonacci(" + n + ") = " + result);
55 }
56 public static void main(String[] args){
57 int n = N;
58 System.out.println("Howdy!");
59 PopAsynchronousTarg pat = new PopAsynchronousTarg();
60 pat.report(n, pat.fibonacci(n));
61 System.out.println("Goodbye from PopAsynchronousTarg!");
62 }
63}
64
65 /********** test program **********/
66
67public class PopAsynchronousTest extends TestScaffold {
68 ReferenceType targetClass;
69 ThreadReference mainThread;
70 int result = -1;
71 boolean harassTarget = true;
72 Object harassLock = new Object();
73
74 PopAsynchronousTest (String args[]) {
75 super(args);
76 }
77
78 public static void main(String[] args) throws Exception {
79 new PopAsynchronousTest(args).startTests();
80 }
81
82
83
84 /********** event handlers **********/
85
86
87 public void breakpointReached(BreakpointEvent event) {
88 harassTarget = false;
89 synchronized(harassLock) {
90 try {
91 StackFrame frame = event.thread().frame(0);
92 LocalVariable lv = frame.visibleVariableByName("result");
93 IntegerValue resultV = (IntegerValue)frame.getValue(lv);
94 result = resultV.value();
95 } catch (Exception exc) {
96 exc.printStackTrace(System.err);
97 failure("TEST FAILURE: exception " + exc);
98 }
99 }
100 }
101
102 /********** test assist **********/
103
104
105 class HarassThread extends Thread {
106 public void run() {
107 int harassCount = 0;
108 try {
109 int prev = 0;
110 int delayTime = 1;
111
112 synchronized(harassLock) {
113 while (harassTarget && (harassCount < 10)) {
114 boolean backoff = true;
115 mainThread.suspend();
116 StackFrame top = mainThread.frame(0);
117 Method meth = top.location().method();
118 String methName = meth.name();
119 if (methName.equals("fibonacci")) {
120 LocalVariable lv = top.visibleVariableByName("n");
121 IntegerValue nV = (IntegerValue)top.getValue(lv);
122 int n = nV.value();
123 if (n != prev) {
124 backoff = false;
125 StackFrame popThis = top;
126 Iterator it = mainThread.frames().iterator();
127
128 /* pop lowest fibonacci frame */
129 while (it.hasNext()) {
130 StackFrame frame = (StackFrame)it.next();
131 if (!frame.location().method().name().equals("fibonacci")) {
132 break;
133 }
134 popThis = frame;
135 }
136 println("popping fibonacci(" + n + ")");
137 mainThread.popFrames(popThis);
138 ++harassCount;
139 prev = n;
140 } else {
141 println("ignoring another fibonacci(" + n + ")");
142 }
143 } else {
144 println("ignoring " + methName);
145 }
146 if (backoff) {
147 delayTime *= 2;
148 } else {
149 delayTime /= 2;
150 if (delayTime < harassCount) {
151 delayTime = harassCount;
152 }
153 }
154 mainThread.resume();
155 println("Delaying for " + delayTime + "ms");
156 Thread.sleep(delayTime);
157 }
158 }
159 } catch (Exception exc) {
160 exc.printStackTrace(System.err);
161 failure("TEST FAILURE: exception " + exc);
162 }
163 println("Harassment complete, count = " + harassCount);
164 }
165 }
166
167 /********** test core **********/
168
169 protected void runTests() throws Exception {
170 /*
171 * Get to the top of main()
172 * to determine targetClass and mainThread
173 */
174 BreakpointEvent bpe = startToMain("PopAsynchronousTarg");
175 targetClass = bpe.location().declaringType();
176 mainThread = bpe.thread();
177 EventRequestManager erm = vm().eventRequestManager();
178
179 /*
180 * Set event requests
181 */
182 List meths = targetClass.methodsByName("report");
183 Location loc = ((Method)(meths.get(0))).location();
184 BreakpointRequest request = erm.createBreakpointRequest(loc);
185 request.enable();
186
187 /*
188 * start popping wildly away
189 */
190 (new HarassThread()).start();
191
192 /*
193 * resume the target listening for events
194 */
195 listenUntilVMDisconnect();
196
197 /*
198 * check result
199 */
200 int correct = (new PopAsynchronousTarg()).
201 fibonacci(PopAsynchronousTarg.N);
202 if (result == correct) {
203 println("Got expected result: " + result);
204 } else {
205 failure("FAIL: expected result: " + correct +
206 ", got: " + result);
207 }
208
209 /*
210 * deal with results of test
211 * if anything has called failure("foo") testFailed will be true
212 */
213 if (!testFailed) {
214 println("PopAsynchronousTest: passed");
215 } else {
216 throw new Exception("PopAsynchronousTest: failed");
217 }
218 }
219}