annotate agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java @ 1552:c18cbe5936b8

6941466: Oracle rebranding changes for Hotspot repositories Summary: Change all the Sun copyrights to Oracle copyright Reviewed-by: ohair
author trims
date Thu, 27 May 2010 19:08:38 -0700
parents a61af66fc99e
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 package sun.jvm.hotspot.livejvm;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import sun.jvm.hotspot.oops.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import sun.jvm.hotspot.runtime.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 /** Provides Java programming language-level interaction with a live
a61af66fc99e Initial load
duke
parents:
diff changeset
32 Java HotSpot VM via the use of the SA's JVMDI module. This is an
a61af66fc99e Initial load
duke
parents:
diff changeset
33 experimental mechanism. The BugSpot debugger should be converted
a61af66fc99e Initial load
duke
parents:
diff changeset
34 to use the JVMDI/JDWP-based JDI implementation for live process
a61af66fc99e Initial load
duke
parents:
diff changeset
35 interaction once the JDI binding for the SA is complete. */
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 public class ServiceabilityAgentJVMDIModule {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 private Debugger dbg;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 private String[] saLibNames;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 private String saLibName;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 private boolean attached;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 private boolean suspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 private static final int JVMDI_EVENT_BREAKPOINT = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 private static final int JVMDI_EVENT_EXCEPTION = 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 private static long timeoutMillis = 3000;
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Values in target process
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Events sent from VM to SA
a61af66fc99e Initial load
duke
parents:
diff changeset
52 private CIntegerAccessor saAttached;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 private CIntegerAccessor saEventPending;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 private CIntegerAccessor saEventKind;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Exception events
a61af66fc99e Initial load
duke
parents:
diff changeset
56 private JNIHandleAccessor saExceptionThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 private JNIHandleAccessor saExceptionClass;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 private JNIid saExceptionMethod;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 private CIntegerAccessor saExceptionLocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 private JNIHandleAccessor saExceptionException;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 private JNIHandleAccessor saExceptionCatchClass;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 private JNIid saExceptionCatchMethod;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 private CIntegerAccessor saExceptionCatchLocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Breakpoint events
a61af66fc99e Initial load
duke
parents:
diff changeset
65 private JNIHandleAccessor saBreakpointThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 private JNIHandleAccessor saBreakpointClass;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 private JNIid saBreakpointMethod;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 private CIntegerAccessor saBreakpointLocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // Commands sent by the SA to the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
70 private int SA_CMD_SUSPEND_ALL;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 private int SA_CMD_RESUME_ALL;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 private int SA_CMD_TOGGLE_BREAKPOINT;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 private int SA_CMD_BUF_SIZE;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 private CIntegerAccessor saCmdPending;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 private CIntegerAccessor saCmdType;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 private CIntegerAccessor saCmdResult;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 private CStringAccessor saCmdResultErrMsg;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // Toggle breakpoint command arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
79 private CStringAccessor saCmdBkptSrcFileName;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 private CStringAccessor saCmdBkptPkgName;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 private CIntegerAccessor saCmdBkptLineNumber;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 private CIntegerAccessor saCmdBkptResWasError;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 private CIntegerAccessor saCmdBkptResLineNumber;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 private CIntegerAccessor saCmdBkptResBCI;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 private CIntegerAccessor saCmdBkptResWasSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 private CStringAccessor saCmdBkptResMethodName;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 private CStringAccessor saCmdBkptResMethodSig;
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 public ServiceabilityAgentJVMDIModule(Debugger dbg, String[] saLibNames) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 this.dbg = dbg;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 this.saLibNames = saLibNames;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 /** Indicates whether a call to attach() should complete without an
a61af66fc99e Initial load
duke
parents:
diff changeset
95 exception. */
a61af66fc99e Initial load
duke
parents:
diff changeset
96 public boolean canAttach() {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 return setupLookup("SA_CMD_SUSPEND_ALL");
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 /** Attempt to initiate a connection with the JVMDI module in the
a61af66fc99e Initial load
duke
parents:
diff changeset
101 target VM. */
a61af66fc99e Initial load
duke
parents:
diff changeset
102 public void attach() throws DebuggerException {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (!canAttach()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 throw new DebuggerException("Unable to initiate symbol lookup in SA's JVMDI module");
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (attached) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 throw new DebuggerException("Already attached");
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // Attempt to look up well-known symbols in the target VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 SA_CMD_SUSPEND_ALL = lookupConstInt("SA_CMD_SUSPEND_ALL");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 SA_CMD_RESUME_ALL = lookupConstInt("SA_CMD_RESUME_ALL");
a61af66fc99e Initial load
duke
parents:
diff changeset
114 SA_CMD_TOGGLE_BREAKPOINT = lookupConstInt("SA_CMD_TOGGLE_BREAKPOINT");
a61af66fc99e Initial load
duke
parents:
diff changeset
115 SA_CMD_BUF_SIZE = lookupConstInt("SA_CMD_BUF_SIZE");
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 saAttached = lookupCInt("saAttached");
a61af66fc99e Initial load
duke
parents:
diff changeset
118 saEventPending = lookupCInt("saEventPending");
a61af66fc99e Initial load
duke
parents:
diff changeset
119 saEventKind = lookupCInt("saEventKind");
a61af66fc99e Initial load
duke
parents:
diff changeset
120 saCmdPending = lookupCInt("saCmdPending");
a61af66fc99e Initial load
duke
parents:
diff changeset
121 saCmdType = lookupCInt("saCmdType");
a61af66fc99e Initial load
duke
parents:
diff changeset
122 saCmdResult = lookupCInt("saCmdResult");
a61af66fc99e Initial load
duke
parents:
diff changeset
123 saCmdResultErrMsg = lookupCString("saCmdResultErrMsg", SA_CMD_BUF_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Toggling of breakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
125 saCmdBkptSrcFileName = lookupCString("saCmdBkptSrcFileName", SA_CMD_BUF_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 saCmdBkptPkgName = lookupCString("saCmdBkptPkgName", SA_CMD_BUF_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 saCmdBkptLineNumber = lookupCInt("saCmdBkptLineNumber");
a61af66fc99e Initial load
duke
parents:
diff changeset
128 saCmdBkptResWasError = lookupCInt("saCmdBkptResWasError");
a61af66fc99e Initial load
duke
parents:
diff changeset
129 saCmdBkptResLineNumber = lookupCInt("saCmdBkptResLineNumber");
a61af66fc99e Initial load
duke
parents:
diff changeset
130 saCmdBkptResBCI = lookupCInt("saCmdBkptResBCI");
a61af66fc99e Initial load
duke
parents:
diff changeset
131 saCmdBkptResWasSet = lookupCInt("saCmdBkptResWasSet");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 saCmdBkptResMethodName = lookupCString("saCmdBkptResMethodName", SA_CMD_BUF_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 saCmdBkptResMethodSig = lookupCString("saCmdBkptResMethodSig", SA_CMD_BUF_SIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Check for existence of symbols needed later
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // FIXME: should probably cache these since we can't support the
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // -Xrun module or the VM getting unloaded anyway
a61af66fc99e Initial load
duke
parents:
diff changeset
138 lookup("saExceptionThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
139 lookup("saExceptionClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 lookup("saExceptionMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 lookup("saExceptionLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 lookup("saExceptionException");
a61af66fc99e Initial load
duke
parents:
diff changeset
143 lookup("saExceptionCatchClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
144 lookup("saExceptionCatchMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
145 lookup("saExceptionCatchLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
146 lookup("saBreakpointThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
147 lookup("saBreakpointClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
148 lookup("saBreakpointMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
149 lookup("saBreakpointLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 saAttached.setValue(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 attached = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 public void detach() {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 saAttached.setValue(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 attached = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 saLibName = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 /** Set the timeout value (in milliseconds) for the VM to reply to
a61af66fc99e Initial load
duke
parents:
diff changeset
162 commands. Once this timeout has elapsed, the VM is assumed to
a61af66fc99e Initial load
duke
parents:
diff changeset
163 have disconnected. Defaults to 3000 milliseconds (3 seconds). */
a61af66fc99e Initial load
duke
parents:
diff changeset
164 public void setCommandTimeout(long millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 timeoutMillis = millis;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 /** Get the timeout value (in milliseconds) for the VM to reply to
a61af66fc99e Initial load
duke
parents:
diff changeset
169 commands. Once this timeout has elapsed, the VM is assumed to
a61af66fc99e Initial load
duke
parents:
diff changeset
170 have disconnected. Defaults to 3000 milliseconds (3 seconds). */
a61af66fc99e Initial load
duke
parents:
diff changeset
171 public long getCommandTimeout() {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return timeoutMillis;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 /** Indicates whether a Java debug event is pending */
a61af66fc99e Initial load
duke
parents:
diff changeset
176 public boolean eventPending() {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return (saEventPending.getValue() != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 /** Poll for event; returns null if none pending. */
a61af66fc99e Initial load
duke
parents:
diff changeset
181 public Event eventPoll() {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (saEventPending.getValue() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 int kind = (int) saEventKind.getValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
187 switch (kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 case JVMDI_EVENT_EXCEPTION: {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 JNIHandleAccessor thread = lookupJNIHandle("saExceptionThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 JNIHandleAccessor clazz = lookupJNIHandle("saExceptionClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
191 JNIid method = lookupJNIid("saExceptionMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 CIntegerAccessor location = lookupCInt("saExceptionLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
193 JNIHandleAccessor exception = lookupJNIHandle("saExceptionException");
a61af66fc99e Initial load
duke
parents:
diff changeset
194 JNIHandleAccessor catchClass = lookupJNIHandle("saExceptionCatchClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
195 JNIid catchMethod = lookupJNIid("saExceptionCatchMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
196 CIntegerAccessor catchLocation = lookupCInt("saExceptionCatchLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return new ExceptionEvent(thread.getValue(), clazz.getValue(), method,
a61af66fc99e Initial load
duke
parents:
diff changeset
198 (int) location.getValue(), exception.getValue(),
a61af66fc99e Initial load
duke
parents:
diff changeset
199 catchClass.getValue(), catchMethod, (int) catchLocation.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 case JVMDI_EVENT_BREAKPOINT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 JNIHandleAccessor thread = lookupJNIHandle("saBreakpointThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
204 JNIHandleAccessor clazz = lookupJNIHandle("saBreakpointClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 JNIid method = lookupJNIid("saBreakpointMethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 CIntegerAccessor location = lookupCInt("saBreakpointLocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
207 return new BreakpointEvent(thread.getValue(), clazz.getValue(),
a61af66fc99e Initial load
duke
parents:
diff changeset
208 method, (int) location.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
212 throw new DebuggerException("Unsupported event type " + kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 /** Continue past current event */
a61af66fc99e Initial load
duke
parents:
diff changeset
217 public void eventContinue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 saEventPending.setValue(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 /** Suspend all Java threads in the target VM. Throws
a61af66fc99e Initial load
duke
parents:
diff changeset
222 DebuggerException if the VM disconnected. */
a61af66fc99e Initial load
duke
parents:
diff changeset
223 public void suspend() {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 saCmdType.setValue(SA_CMD_SUSPEND_ALL);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 saCmdPending.setValue(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 waitForCommandCompletion();
a61af66fc99e Initial load
duke
parents:
diff changeset
227 suspended = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 /** Resume all Java threads in the target VM. Throws
a61af66fc99e Initial load
duke
parents:
diff changeset
231 DebuggerException if the VM disconnected. */
a61af66fc99e Initial load
duke
parents:
diff changeset
232 public void resume() {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 saCmdType.setValue(SA_CMD_RESUME_ALL);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 saCmdPending.setValue(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 waitForCommandCompletion();
a61af66fc99e Initial load
duke
parents:
diff changeset
236 suspended = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 /** Indicates whether all Java threads have been suspended via this
a61af66fc99e Initial load
duke
parents:
diff changeset
240 interface. */
a61af66fc99e Initial load
duke
parents:
diff changeset
241 public boolean isSuspended() {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 return suspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 /** Information about toggling of breakpoints */
a61af66fc99e Initial load
duke
parents:
diff changeset
246 public static class BreakpointToggleResult {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 private boolean success;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 private String errMsg;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 private int lineNumber;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 private int bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 private boolean wasSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 private String methodName;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 private String methodSig;
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 /** Success constructor */
a61af66fc99e Initial load
duke
parents:
diff changeset
256 public BreakpointToggleResult(int lineNumber, int bci, boolean wasSet,
a61af66fc99e Initial load
duke
parents:
diff changeset
257 String methodName, String methodSig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 this.lineNumber = lineNumber;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 this.bci = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 this.wasSet = wasSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 this.methodName = methodName;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 this.methodSig = methodSig;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 success = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 /** Failure constructor */
a61af66fc99e Initial load
duke
parents:
diff changeset
267 public BreakpointToggleResult(String errMsg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 this.errMsg = errMsg;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 success = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 /** Indicates whether this represents a successful return or not */
a61af66fc99e Initial load
duke
parents:
diff changeset
273 public boolean getSuccess() { return success; }
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 /** Valid only if getSuccess() returns false */
a61af66fc99e Initial load
duke
parents:
diff changeset
276 public String getErrMsg() { return errMsg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 /** Line number at which breakpoint toggle occurred; valid only if
a61af66fc99e Initial load
duke
parents:
diff changeset
279 getSuccess() returns true. */
a61af66fc99e Initial load
duke
parents:
diff changeset
280 public int getLineNumber() { return lineNumber; }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 /** BCI at which breakpoint toggle occurred; valid only if
a61af66fc99e Initial load
duke
parents:
diff changeset
283 getSuccess() returns true. */
a61af66fc99e Initial load
duke
parents:
diff changeset
284 public int getBCI() { return bci; }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 /** Indicates whether the breakpoint toggle was the set of a
a61af66fc99e Initial load
duke
parents:
diff changeset
287 breakpoint or not; valid only if getSuccess() returns true. */
a61af66fc99e Initial load
duke
parents:
diff changeset
288 public boolean getWasSet() { return wasSet; }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 /** Method name in which the breakpoint toggle occurred; valid
a61af66fc99e Initial load
duke
parents:
diff changeset
291 only if getSuccess() returns true. */
a61af66fc99e Initial load
duke
parents:
diff changeset
292 public String getMethodName() { return methodName; }
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 /** Method signature in which the breakpoint toggle occurred;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 valid only if getSuccess() returns true. */
a61af66fc99e Initial load
duke
parents:
diff changeset
296 public String getMethodSignature() { return methodSig; }
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 /** Toggle a breakpoint. Throws DebuggerException if a real error
a61af66fc99e Initial load
duke
parents:
diff changeset
300 occurred; otherwise returns non-null BreakpointToggleResult. The
a61af66fc99e Initial load
duke
parents:
diff changeset
301 work of scanning the loaded classes is done in the target VM
a61af66fc99e Initial load
duke
parents:
diff changeset
302 because it turns out to be significantly faster than scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
303 through the system dictionary from the SA, and interactivity
a61af66fc99e Initial load
duke
parents:
diff changeset
304 when setting breakpoints is important. */
a61af66fc99e Initial load
duke
parents:
diff changeset
305 public BreakpointToggleResult toggleBreakpoint(String srcFileName,
a61af66fc99e Initial load
duke
parents:
diff changeset
306 String pkgName,
a61af66fc99e Initial load
duke
parents:
diff changeset
307 int lineNo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 saCmdBkptSrcFileName.setValue(srcFileName);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 saCmdBkptPkgName.setValue(pkgName);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 saCmdBkptLineNumber.setValue(lineNo);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 saCmdType.setValue(SA_CMD_TOGGLE_BREAKPOINT);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 saCmdPending.setValue(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (waitForCommandCompletion(true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 return new BreakpointToggleResult((int) saCmdBkptResLineNumber.getValue(),
a61af66fc99e Initial load
duke
parents:
diff changeset
315 (int) saCmdBkptResBCI.getValue(),
a61af66fc99e Initial load
duke
parents:
diff changeset
316 (saCmdBkptResWasSet.getValue() != 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
317 saCmdBkptResMethodName.getValue(),
a61af66fc99e Initial load
duke
parents:
diff changeset
318 saCmdBkptResMethodSig.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
319 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 return new BreakpointToggleResult(saCmdResultErrMsg.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
327 //
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 private CIntegerAccessor lookupCInt(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return new CIntegerAccessor(lookup(symbolName), 4, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 private CStringAccessor lookupCString(String symbolName, int bufLen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return new CStringAccessor(lookup(symbolName), bufLen);
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 private JNIHandleAccessor lookupJNIHandle(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 return new JNIHandleAccessor(lookup(symbolName), VM.getVM().getObjectHeap());
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 private JNIid lookupJNIid(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 Address idAddr = lookup(symbolName).getAddressAt(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (idAddr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346 return new JNIid(idAddr, VM.getVM().getObjectHeap());
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 private int lookupConstInt(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 Address addr = lookup(symbolName);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 return (int) addr.getCIntegerAt(0, 4, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 private boolean setupLookup(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 if (saLibName == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 for (int i = 0; i < saLibNames.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 Address addr = dbg.lookup(saLibNames[i], symbolName);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if (addr != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 saLibName = saLibNames[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
360 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 private Address lookup(String symbolName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (saLibName == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 for (int i = 0; i < saLibNames.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 Address addr = dbg.lookup(saLibNames[i], symbolName);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (addr != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 saLibName = saLibNames[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
374 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 throw new DebuggerException("Unable to find symbol " + symbolName + " in any of the known names for the SA");
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 Address addr = dbg.lookup(saLibName, symbolName);
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (addr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 throw new DebuggerException("Unable to find symbol " + symbolName + " in " + saLibName);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 private void waitForCommandCompletion() {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 waitForCommandCompletion(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 /** Returns true if command succeeded, false if not */
a61af66fc99e Initial load
duke
parents:
diff changeset
392 private boolean waitForCommandCompletion(boolean forBreakpoint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 long start = System.currentTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
394 long cur = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 while ((saCmdPending.getValue() != 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
396 (cur - start < timeoutMillis)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 java.lang.Thread.currentThread().sleep(10);
a61af66fc99e Initial load
duke
parents:
diff changeset
399 } catch (InterruptedException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 cur = System.currentTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if (saCmdPending.getValue() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 detach();
a61af66fc99e Initial load
duke
parents:
diff changeset
405 throw new DebuggerException("VM appears to have died");
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407 boolean succeeded = saCmdResult.getValue() == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (!succeeded &&
a61af66fc99e Initial load
duke
parents:
diff changeset
409 (!forBreakpoint || saCmdBkptResWasError.getValue() != 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 String err = saCmdResultErrMsg.getValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
411 throw new DebuggerException("Error executing JVMDI command: " + err);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 return succeeded;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }