annotate agent/test/jdi/TestScaffold.java @ 3011:f00918f35c7f

inlining and runtime interface related changes: added codeSize() and compilerStorage() to RiMethod HotSpotMethodResolved uses reflective methods instead of vmIds and survives compilations HotSpotResolvedType.isInitialized not represented as field (can change) inlining stores graphs into method objects and reuses them
author Lukas Stadler <lukas.stadler@jku.at>
date Thu, 16 Jun 2011 20:36:17 +0200
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 import com.sun.jdi.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
26 import com.sun.jdi.request.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import com.sun.jdi.event.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
32 * Framework used by all JDI regression tests
a61af66fc99e Initial load
duke
parents:
diff changeset
33 */
a61af66fc99e Initial load
duke
parents:
diff changeset
34 abstract public class TestScaffold extends TargetAdapter {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 private boolean shouldTrace = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 private VMConnection connection;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 private VirtualMachine vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 private EventRequestManager requestManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 private List listeners = Collections.synchronizedList(new LinkedList());
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
42 * We create a VMDeathRequest, SUSPEND_ALL, to sync the BE and FE.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 */
a61af66fc99e Initial load
duke
parents:
diff changeset
44 //private VMDeathRequest ourVMDeathRequest = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 Object ourVMDeathRequest = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
48 * We create an ExceptionRequest, SUSPEND_NONE so that we can
a61af66fc99e Initial load
duke
parents:
diff changeset
49 * catch it and output a msg if an exception occurs in the
a61af66fc99e Initial load
duke
parents:
diff changeset
50 * debuggee.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 */
a61af66fc99e Initial load
duke
parents:
diff changeset
52 private ExceptionRequest ourExceptionRequest = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
55 * If we do catch an uncaught exception, we set this true
a61af66fc99e Initial load
duke
parents:
diff changeset
56 * so the testcase can find out if it wants to.
a61af66fc99e Initial load
duke
parents:
diff changeset
57 */
a61af66fc99e Initial load
duke
parents:
diff changeset
58 private boolean exceptionCaught = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 ThreadReference vmStartThread = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 boolean vmDied = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 boolean vmDisconnected = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 final String[] args;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 protected boolean testFailed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static private class ArgInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 String targetVMArgs = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
67 String targetAppCommandLine = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
68 String connectorSpec = "com.sun.jdi.CommandLineLaunch:";
a61af66fc99e Initial load
duke
parents:
diff changeset
69 int traceFlags = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
73 * An easy way to sleep for awhile
a61af66fc99e Initial load
duke
parents:
diff changeset
74 */
a61af66fc99e Initial load
duke
parents:
diff changeset
75 public void mySleep(int millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 Thread.sleep(millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 } catch (InterruptedException ee) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 boolean getExceptionCaught() {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 return exceptionCaught;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 void setExceptionCaught(boolean value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 exceptionCaught = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
91 * Return true if eventSet contains the VMDeathEvent for the request in
a61af66fc99e Initial load
duke
parents:
diff changeset
92 * the ourVMDeathRequest ivar.
a61af66fc99e Initial load
duke
parents:
diff changeset
93 */
a61af66fc99e Initial load
duke
parents:
diff changeset
94 private boolean containsOurVMDeathRequest(EventSet eventSet) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if (ourVMDeathRequest != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 Iterator myIter = eventSet.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 while (myIter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 Event myEvent = (Event)myIter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (!(myEvent instanceof VMDeathEvent)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // We assume that an EventSet contains only VMDeathEvents
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // or no VMDeathEvents.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 if (ourVMDeathRequest.equals(myEvent.request())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 /************************************************************************
a61af66fc99e Initial load
duke
parents:
diff changeset
113 * The following methods override those in our base class, TargetAdapter.
a61af66fc99e Initial load
duke
parents:
diff changeset
114 *************************************************************************/
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
117 * Events handled directly by scaffold always resume (well, almost always)
a61af66fc99e Initial load
duke
parents:
diff changeset
118 */
a61af66fc99e Initial load
duke
parents:
diff changeset
119 public void eventSetComplete(EventSet set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // The listener in connect(..) resumes after receiving our
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // special VMDeathEvent. We can't also do the resume
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // here or we will probably get a VMDisconnectedException
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (!containsOurVMDeathRequest(set)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 traceln("TS: set.resume() called");
a61af66fc99e Initial load
duke
parents:
diff changeset
125 set.resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
130 * This method sets up default requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 * Testcases can override this to change default behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 */
a61af66fc99e Initial load
duke
parents:
diff changeset
133 protected void createDefaultEventRequests() {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 createDefaultVMDeathRequest();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 createDefaultExceptionRequest();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
139 * We want the BE to stop when it issues a VMDeathEvent in order to
a61af66fc99e Initial load
duke
parents:
diff changeset
140 * give the FE time to complete handling events that occured before
a61af66fc99e Initial load
duke
parents:
diff changeset
141 * the VMDeath. When we get the VMDeathEvent for this request in
a61af66fc99e Initial load
duke
parents:
diff changeset
142 * the listener in connect(), we will do a resume.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 * If a testcase wants to do something special with VMDeathEvent's,
a61af66fc99e Initial load
duke
parents:
diff changeset
144 * then it should override this method with an empty method or
a61af66fc99e Initial load
duke
parents:
diff changeset
145 * whatever in order to suppress the automatic resume. The testcase
a61af66fc99e Initial load
duke
parents:
diff changeset
146 * will then be responsible for the handling of VMDeathEvents. It
a61af66fc99e Initial load
duke
parents:
diff changeset
147 * has to be sure that it does a resume if it gets a VMDeathEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
148 * with SUSPEND_ALL, and it has to be sure that it doesn't do a
a61af66fc99e Initial load
duke
parents:
diff changeset
149 * resume after getting a VMDeath with SUSPEND_NONE (the automatically
a61af66fc99e Initial load
duke
parents:
diff changeset
150 * generated VMDeathEvent.)
a61af66fc99e Initial load
duke
parents:
diff changeset
151 */
a61af66fc99e Initial load
duke
parents:
diff changeset
152 protected void createDefaultVMDeathRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // ourVMDeathRequest = requestManager.createVMDeathRequest();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // ourVMDeathRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // ourVMDeathRequest.enable();
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
159 * This will allow us to print a warning if a debuggee gets an
a61af66fc99e Initial load
duke
parents:
diff changeset
160 * unexpected exception. The unexpected exception will be handled in
a61af66fc99e Initial load
duke
parents:
diff changeset
161 * the exceptionThrown method in the listener created in the connect()
a61af66fc99e Initial load
duke
parents:
diff changeset
162 * method.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 * If a testcase does not want an uncaught exception to cause a
a61af66fc99e Initial load
duke
parents:
diff changeset
164 * msg, it must override this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 */
a61af66fc99e Initial load
duke
parents:
diff changeset
166 protected void createDefaultExceptionRequest() {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 ourExceptionRequest = requestManager.createExceptionRequest(null,
a61af66fc99e Initial load
duke
parents:
diff changeset
168 false, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // We can't afford to make this be other than SUSPEND_NONE. Otherwise,
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // it would have to be resumed. If our connect() listener resumes it,
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // what about the case where the EventSet contains other events with
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // SUSPEND_ALL and there are other listeners who expect the BE to still
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // be suspended when their handlers get called?
a61af66fc99e Initial load
duke
parents:
diff changeset
175 ourExceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 ourExceptionRequest.enable();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 private class EventHandler implements Runnable {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 EventHandler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 Thread thread = new Thread(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 thread.setDaemon(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 thread.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 private void notifyEvent(TargetListener listener, Event event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (event instanceof BreakpointEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 listener.breakpointReached((BreakpointEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 } else if (event instanceof ExceptionEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 listener.exceptionThrown((ExceptionEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 } else if (event instanceof StepEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 listener.stepCompleted((StepEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 } else if (event instanceof ClassPrepareEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 listener.classPrepared((ClassPrepareEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 } else if (event instanceof ClassUnloadEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 listener.classUnloaded((ClassUnloadEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 } else if (event instanceof MethodEntryEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 listener.methodEntered((MethodEntryEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 } else if (event instanceof MethodExitEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 listener.methodExited((MethodExitEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 } else if (event instanceof AccessWatchpointEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 listener.fieldAccessed((AccessWatchpointEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 } else if (event instanceof ModificationWatchpointEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 listener.fieldModified((ModificationWatchpointEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 } else if (event instanceof ThreadStartEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 listener.threadStarted((ThreadStartEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 } else if (event instanceof ThreadDeathEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 listener.threadDied((ThreadDeathEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 } else if (event instanceof VMStartEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 listener.vmStarted((VMStartEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 } else if (event instanceof VMDeathEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 listener.vmDied((VMDeathEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 } else if (event instanceof VMDisconnectEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 listener.vmDisconnected((VMDisconnectEvent)event);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 throw new InternalError("Unknown event type: " + event.getClass());
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 private void traceSuspendPolicy(int policy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if (shouldTrace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 switch (policy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 case EventRequest.SUSPEND_NONE:
a61af66fc99e Initial load
duke
parents:
diff changeset
224 traceln("TS: eventHandler: suspend = SUSPEND_NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 case EventRequest.SUSPEND_ALL:
a61af66fc99e Initial load
duke
parents:
diff changeset
227 traceln("TS: eventHandler: suspend = SUSPEND_ALL");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 case EventRequest.SUSPEND_EVENT_THREAD:
a61af66fc99e Initial load
duke
parents:
diff changeset
230 traceln("TS: eventHandler: suspend = SUSPEND_EVENT_THREAD");
a61af66fc99e Initial load
duke
parents:
diff changeset
231 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 public void run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 boolean connected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 EventSet set = vm.eventQueue().remove();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 traceSuspendPolicy(set.suspendPolicy());
a61af66fc99e Initial load
duke
parents:
diff changeset
242 synchronized (listeners) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 ListIterator iter = listeners.listIterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
244 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 TargetListener listener = (TargetListener)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
246 traceln("TS: eventHandler: listener = " + listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 listener.eventSetReceived(set);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (listener.shouldRemoveListener()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 iter.remove();
a61af66fc99e Initial load
duke
parents:
diff changeset
250 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 Iterator jter = set.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
252 while (jter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 Event event = (Event)jter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
254 traceln("TS: eventHandler: event = " + event.getClass());
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 if (event instanceof VMDisconnectEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 connected = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 listener.eventReceived(event);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (listener.shouldRemoveListener()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 iter.remove();
a61af66fc99e Initial load
duke
parents:
diff changeset
262 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 notifyEvent(listener, event);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (listener.shouldRemoveListener()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 iter.remove();
a61af66fc99e Initial load
duke
parents:
diff changeset
267 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270 traceln("TS: eventHandler: end of events loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (!listener.shouldRemoveListener()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 traceln("TS: eventHandler: calling ESC");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 listener.eventSetComplete(set);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if (listener.shouldRemoveListener()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 iter.remove();
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 traceln("TS: eventHandler: end of listeners loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 } catch (InterruptedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 traceln("TS: eventHandler: InterruptedException");
a61af66fc99e Initial load
duke
parents:
diff changeset
284 } catch (Exception e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 failure("FAILED: Exception occured in eventHandler: " + e);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 e.printStackTrace();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 connected = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 synchronized(TestScaffold.this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // This will make the waiters such as waitForVMDisconnect
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // exit their wait loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 vmDisconnected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 TestScaffold.this.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 traceln("TS: eventHandler: End of outerloop");
a61af66fc99e Initial load
duke
parents:
diff changeset
296 } while (connected);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 traceln("TS: eventHandler: finished");
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
302 * Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
303 */
a61af66fc99e Initial load
duke
parents:
diff changeset
304 public TestScaffold(String[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 this.args = args;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 public void enableScaffoldTrace() {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 this.shouldTrace = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 public void disableScaffoldTrace() {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 this.shouldTrace = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 protected void startUp(String targetName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 List argList = new ArrayList(Arrays.asList(args));
a61af66fc99e Initial load
duke
parents:
diff changeset
319 argList.add(targetName);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 println("run args: " + argList);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 connect((String[]) argList.toArray(args));
a61af66fc99e Initial load
duke
parents:
diff changeset
322 waitForVMStart();
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 protected BreakpointEvent startToMain(String targetName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 startUp(targetName);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 traceln("TS: back from startUp");
a61af66fc99e Initial load
duke
parents:
diff changeset
328 BreakpointEvent bpr = resumeTo(targetName, "main", "([Ljava/lang/String;)V");
a61af66fc99e Initial load
duke
parents:
diff changeset
329 waitForInput();
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return bpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 protected void waitForInput() {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (System.getProperty("jpda.wait") != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 System.err.println("Press <enter> to continue");
a61af66fc99e Initial load
duke
parents:
diff changeset
337 System.in.read();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 System.err.println("running...");
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 } catch(Exception e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
346 * Test cases should implement tests in runTests and should
a61af66fc99e Initial load
duke
parents:
diff changeset
347 * initiate testing by calling run().
a61af66fc99e Initial load
duke
parents:
diff changeset
348 */
a61af66fc99e Initial load
duke
parents:
diff changeset
349 abstract protected void runTests() throws Exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 final public void startTests() throws Exception {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 runTests();
a61af66fc99e Initial load
duke
parents:
diff changeset
354 } finally {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 protected void println(String str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 System.err.println(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 protected void print(String str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 System.err.print(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 protected void traceln(String str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 if (shouldTrace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 println(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 protected void failure(String str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 println(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 testFailed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 private ArgInfo parseArgs(String args[]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 ArgInfo argInfo = new ArgInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
380 for (int i = 0; i < args.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (args[i].equals("-connect")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 argInfo.connectorSpec = args[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
384 } else if (args[i].equals("-trace")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
386 argInfo.traceFlags = Integer.decode(args[i]).intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
387 } else if (args[i].startsWith("-J")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 argInfo.targetVMArgs += (args[i].substring(2) + ' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
391 * classpath can span two arguments so we need to handle
a61af66fc99e Initial load
duke
parents:
diff changeset
392 * it specially.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 */
a61af66fc99e Initial load
duke
parents:
diff changeset
394 if (args[i].equals("-J-classpath")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 argInfo.targetVMArgs += (args[i] + ' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 argInfo.targetAppCommandLine += (args[i] + ' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 return argInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
406 * This is called to connect to a debuggee VM. It starts the VM and
a61af66fc99e Initial load
duke
parents:
diff changeset
407 * installs a listener to catch VMStartEvent, our default events, and
a61af66fc99e Initial load
duke
parents:
diff changeset
408 * VMDisconnectedEvent. When these events appear, that is remembered
a61af66fc99e Initial load
duke
parents:
diff changeset
409 * and waiters are notified.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 * This is normally called in the main thread of the test case.
a61af66fc99e Initial load
duke
parents:
diff changeset
411 * It starts up an EventHandler thread that gets events coming in
a61af66fc99e Initial load
duke
parents:
diff changeset
412 * from the debuggee and distributes them to listeners. That thread
a61af66fc99e Initial load
duke
parents:
diff changeset
413 * keeps running until a VMDisconnectedEvent occurs or some exception
a61af66fc99e Initial load
duke
parents:
diff changeset
414 * occurs during its processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
415 *
a61af66fc99e Initial load
duke
parents:
diff changeset
416 * The 'listenUntilVMDisconnect' method adds 'this' as a listener.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 * This means that 'this's vmDied method will get called. This has a
a61af66fc99e Initial load
duke
parents:
diff changeset
418 * default impl in TargetAdapter.java which can be overridden in the
a61af66fc99e Initial load
duke
parents:
diff changeset
419 * testcase.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 *
a61af66fc99e Initial load
duke
parents:
diff changeset
421 * waitForRequestedEvent also adds an adaptor listener that listens
a61af66fc99e Initial load
duke
parents:
diff changeset
422 * for the particular event it is supposed to wait for (and it also
a61af66fc99e Initial load
duke
parents:
diff changeset
423 * catches VMDisconnectEvents.) This listener is removed once
a61af66fc99e Initial load
duke
parents:
diff changeset
424 * its eventReceived method is called.
a61af66fc99e Initial load
duke
parents:
diff changeset
425 * waitForRequestedEvent is called by most of the methods to do bkpts,
a61af66fc99e Initial load
duke
parents:
diff changeset
426 * etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
427 */
a61af66fc99e Initial load
duke
parents:
diff changeset
428 public void connect(String args[]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 ArgInfo argInfo = parseArgs(args);
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 argInfo.targetVMArgs += VMConnection.getDebuggeeVMOptions();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 connection = new VMConnection(argInfo.connectorSpec,
a61af66fc99e Initial load
duke
parents:
diff changeset
433 argInfo.traceFlags);
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 addListener(new TargetAdapter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 public void eventSetComplete(EventSet set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (TestScaffold.this.containsOurVMDeathRequest(set)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 traceln("TS: connect: set.resume() called");
a61af66fc99e Initial load
duke
parents:
diff changeset
439 set.resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Note that we want to do the above resume before
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // waking up any sleepers.
a61af66fc99e Initial load
duke
parents:
diff changeset
443 synchronized(TestScaffold.this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 TestScaffold.this.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 public void vmStarted(VMStartEvent event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 synchronized(TestScaffold.this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 vmStartThread = event.thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
452 TestScaffold.this.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
456 * By default, we catch uncaught exceptions and print a msg.
a61af66fc99e Initial load
duke
parents:
diff changeset
457 * The testcase must override the createDefaultExceptionRequest
a61af66fc99e Initial load
duke
parents:
diff changeset
458 * method if it doesn't want this behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
459 */
a61af66fc99e Initial load
duke
parents:
diff changeset
460 public void exceptionThrown(ExceptionEvent event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (TestScaffold.this.ourExceptionRequest != null &&
a61af66fc99e Initial load
duke
parents:
diff changeset
462 TestScaffold.this.ourExceptionRequest.equals(
a61af66fc99e Initial load
duke
parents:
diff changeset
463 event.request())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 println("Note: Unexpected Debuggee Exception: " +
a61af66fc99e Initial load
duke
parents:
diff changeset
465 event.exception().referenceType().name() +
a61af66fc99e Initial load
duke
parents:
diff changeset
466 " at line " + event.location().lineNumber());
a61af66fc99e Initial load
duke
parents:
diff changeset
467 TestScaffold.this.exceptionCaught = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 public void vmDied(VMDeathEvent event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 vmDied = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 traceln("TS: vmDied called");
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 public void vmDisconnected(VMDisconnectEvent event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 synchronized(TestScaffold.this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 vmDisconnected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 TestScaffold.this.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 });
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (connection.connector().name().equals("com.sun.jdi.CommandLineLaunch")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (argInfo.targetVMArgs.length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 if (connection.connectorArg("options").length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 throw new IllegalArgumentException("VM options in two places");
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 connection.setConnectorArg("options", argInfo.targetVMArgs);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (argInfo.targetAppCommandLine.length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 if (connection.connectorArg("main").length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 throw new IllegalArgumentException("Command line in two places");
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494 connection.setConnectorArg("main", argInfo.targetAppCommandLine);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 vm = connection.open();
a61af66fc99e Initial load
duke
parents:
diff changeset
499 requestManager = vm.eventRequestManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 createDefaultEventRequests();
a61af66fc99e Initial load
duke
parents:
diff changeset
501 new EventHandler();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 public VirtualMachine vm() {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 return vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 public EventRequestManager eventRequestManager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return requestManager;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 public void addListener(TargetListener listener) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 traceln("TS: Adding listener " + listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 listeners.add(listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 public void removeListener(TargetListener listener) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 traceln("TS: Removing listener " + listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 listeners.remove(listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 protected void listenUntilVMDisconnect() {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 addListener (this);
a61af66fc99e Initial load
duke
parents:
diff changeset
527 } catch (Exception ex){
a61af66fc99e Initial load
duke
parents:
diff changeset
528 ex.printStackTrace();
a61af66fc99e Initial load
duke
parents:
diff changeset
529 testFailed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 } finally {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // Allow application to complete and shut down
a61af66fc99e Initial load
duke
parents:
diff changeset
532 resumeToVMDisconnect();
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 public synchronized ThreadReference waitForVMStart() {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 while ((vmStartThread == null) && !vmDisconnected) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
540 } catch (InterruptedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 if (vmStartThread == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 throw new VMDisconnectedException();
a61af66fc99e Initial load
duke
parents:
diff changeset
546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 return vmStartThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 public synchronized void waitForVMDisconnect() {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 traceln("TS: waitForVMDisconnect");
a61af66fc99e Initial load
duke
parents:
diff changeset
553 while (!vmDisconnected) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
555 wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
556 } catch (InterruptedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 traceln("TS: waitForVMDisconnect: done");
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 public Event waitForRequestedEvent(final EventRequest request) {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 class EventNotification {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 Event event;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 boolean disconnected = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567 final EventNotification en = new EventNotification();
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 TargetAdapter adapter = new TargetAdapter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 public void eventReceived(Event event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 if (request.equals(event.request())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 traceln("TS:Listener2: got requested event");
a61af66fc99e Initial load
duke
parents:
diff changeset
573 synchronized (en) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 en.event = event;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 en.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577 removeThisListener();
a61af66fc99e Initial load
duke
parents:
diff changeset
578 } else if (event instanceof VMDisconnectEvent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 traceln("TS:Listener2: got VMDisconnectEvent");
a61af66fc99e Initial load
duke
parents:
diff changeset
580 synchronized (en) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 en.disconnected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
582 en.notifyAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 removeThisListener();
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 };
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 addListener(adapter);
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 synchronized (en) {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 traceln("TS: waitForRequestedEvent: vm.resume called");
a61af66fc99e Initial load
duke
parents:
diff changeset
594 vm.resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 while (!en.disconnected && (en.event == null)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 en.wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 } catch (InterruptedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 if (en.disconnected) {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 throw new RuntimeException("VM Disconnected before requested event occurred");
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607 return en.event;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 private StepEvent doStep(ThreadReference thread, int gran, int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 final StepRequest sr =
a61af66fc99e Initial load
duke
parents:
diff changeset
612 requestManager.createStepRequest(thread, gran, depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 sr.addClassExclusionFilter("java.*");
a61af66fc99e Initial load
duke
parents:
diff changeset
615 sr.addClassExclusionFilter("sun.*");
a61af66fc99e Initial load
duke
parents:
diff changeset
616 sr.addClassExclusionFilter("com.sun.*");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 sr.addCountFilter(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 sr.enable();
a61af66fc99e Initial load
duke
parents:
diff changeset
619 StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr);
a61af66fc99e Initial load
duke
parents:
diff changeset
620 requestManager.deleteEventRequest(sr);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 return retEvent;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 public StepEvent stepIntoInstruction(ThreadReference thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_INTO);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 public StepEvent stepIntoLine(ThreadReference thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 public StepEvent stepOverInstruction(ThreadReference thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
633 return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OVER);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 public StepEvent stepOverLine(ThreadReference thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OVER);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 public StepEvent stepOut(ThreadReference thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OUT);
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 public BreakpointEvent resumeTo(Location loc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 final BreakpointRequest request =
a61af66fc99e Initial load
duke
parents:
diff changeset
646 requestManager.createBreakpointRequest(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 request.addCountFilter(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
648 request.enable();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 return (BreakpointEvent)waitForRequestedEvent(request);
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 public ReferenceType findReferenceType(String name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 List rts = vm.classesByName(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 Iterator iter = rts.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 ReferenceType rt = (ReferenceType)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
657 if (rt.name().equals(name)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
658 return rt;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 public Method findMethod(ReferenceType rt, String name, String signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 List methods = rt.methods();
a61af66fc99e Initial load
duke
parents:
diff changeset
666 Iterator iter = methods.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
667 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
668 Method method = (Method)iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if (method.name().equals(name) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
670 method.signature().equals(signature)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
671 return method;
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 public Location findLocation(ReferenceType rt, int lineNumber)
a61af66fc99e Initial load
duke
parents:
diff changeset
678 throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 List locs = rt.locationsOfLine(lineNumber);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 if (locs.size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 throw new IllegalArgumentException("Bad line number");
a61af66fc99e Initial load
duke
parents:
diff changeset
682 } else if (locs.size() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 throw new IllegalArgumentException("Line number has multiple locations");
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 return (Location)locs.get(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 public BreakpointEvent resumeTo(String clsName, String methodName,
a61af66fc99e Initial load
duke
parents:
diff changeset
690 String methodSignature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
691 ReferenceType rt = findReferenceType(clsName);
a61af66fc99e Initial load
duke
parents:
diff changeset
692 if (rt == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 rt = resumeToPrepareOf(clsName).referenceType();
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 Method method = findMethod(rt, methodName, methodSignature);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 if (method == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
698 throw new IllegalArgumentException("Bad method name/signature");
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return resumeTo(method.location());
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 public BreakpointEvent resumeTo(String clsName, int lineNumber) throws AbsentInformationException {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 ReferenceType rt = findReferenceType(clsName);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if (rt == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 rt = resumeToPrepareOf(clsName).referenceType();
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 return resumeTo(findLocation(rt, lineNumber));
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 public ClassPrepareEvent resumeToPrepareOf(String className) {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 final ClassPrepareRequest request =
a61af66fc99e Initial load
duke
parents:
diff changeset
715 requestManager.createClassPrepareRequest();
a61af66fc99e Initial load
duke
parents:
diff changeset
716 request.addClassFilter(className);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 request.addCountFilter(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
718 request.enable();
a61af66fc99e Initial load
duke
parents:
diff changeset
719 return (ClassPrepareEvent)waitForRequestedEvent(request);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 public void resumeToVMDisconnect() {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 traceln("TS: resumeToVMDisconnect: vm.resume called");
a61af66fc99e Initial load
duke
parents:
diff changeset
725 vm.resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
726 } catch (VMDisconnectedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // clean up below
a61af66fc99e Initial load
duke
parents:
diff changeset
728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
729 waitForVMDisconnect();
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 public void shutdown() {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 shutdown(null);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 public void shutdown(String message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 traceln("TS: shutdown: vmDied= " + vmDied +
a61af66fc99e Initial load
duke
parents:
diff changeset
738 ", vmDisconnected= " + vmDisconnected +
a61af66fc99e Initial load
duke
parents:
diff changeset
739 ", connection = " + connection);
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if ((connection != null)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 connection.disposeVM();
a61af66fc99e Initial load
duke
parents:
diff changeset
744 } catch (VMDisconnectedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Shutting down after the VM has gone away. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // not an error, and we just ignore it.
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 traceln("TS: shutdown: disposeVM not called");
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751 if (message != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 println(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 vmDied = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 vmDisconnected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }