1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker *
5*e82f7db8SAndroid Build Coastguard Worker * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker * published by the Free Software Foundation. Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker *
11*e82f7db8SAndroid Build Coastguard Worker * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker *
17*e82f7db8SAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker *
21*e82f7db8SAndroid Build Coastguard Worker * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker * questions.
24*e82f7db8SAndroid Build Coastguard Worker */
25*e82f7db8SAndroid Build Coastguard Worker
26*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
27*e82f7db8SAndroid Build Coastguard Worker #include "transport.h"
28*e82f7db8SAndroid Build Coastguard Worker #include "debugLoop.h"
29*e82f7db8SAndroid Build Coastguard Worker #include "sys.h"
30*e82f7db8SAndroid Build Coastguard Worker
31*e82f7db8SAndroid Build Coastguard Worker static jdwpTransportEnv *transport;
32*e82f7db8SAndroid Build Coastguard Worker static jrawMonitorID listenerLock;
33*e82f7db8SAndroid Build Coastguard Worker static jrawMonitorID sendLock;
34*e82f7db8SAndroid Build Coastguard Worker
35*e82f7db8SAndroid Build Coastguard Worker /*
36*e82f7db8SAndroid Build Coastguard Worker * data structure used for passing transport info from thread to thread
37*e82f7db8SAndroid Build Coastguard Worker */
38*e82f7db8SAndroid Build Coastguard Worker typedef struct TransportInfo {
39*e82f7db8SAndroid Build Coastguard Worker char *name;
40*e82f7db8SAndroid Build Coastguard Worker jdwpTransportEnv *transport;
41*e82f7db8SAndroid Build Coastguard Worker char *address;
42*e82f7db8SAndroid Build Coastguard Worker long timeout;
43*e82f7db8SAndroid Build Coastguard Worker } TransportInfo;
44*e82f7db8SAndroid Build Coastguard Worker
45*e82f7db8SAndroid Build Coastguard Worker static struct jdwpTransportCallback callback = {jvmtiAllocate, jvmtiDeallocate};
46*e82f7db8SAndroid Build Coastguard Worker
47*e82f7db8SAndroid Build Coastguard Worker /*
48*e82f7db8SAndroid Build Coastguard Worker * Print the last transport error
49*e82f7db8SAndroid Build Coastguard Worker */
50*e82f7db8SAndroid Build Coastguard Worker static void
printLastError(jdwpTransportEnv * t,jdwpTransportError err)51*e82f7db8SAndroid Build Coastguard Worker printLastError(jdwpTransportEnv *t, jdwpTransportError err)
52*e82f7db8SAndroid Build Coastguard Worker {
53*e82f7db8SAndroid Build Coastguard Worker char *msg;
54*e82f7db8SAndroid Build Coastguard Worker jbyte *utf8msg;
55*e82f7db8SAndroid Build Coastguard Worker jdwpTransportError rv;
56*e82f7db8SAndroid Build Coastguard Worker
57*e82f7db8SAndroid Build Coastguard Worker msg = NULL;
58*e82f7db8SAndroid Build Coastguard Worker utf8msg = NULL;
59*e82f7db8SAndroid Build Coastguard Worker rv = (*t)->GetLastError(t, &msg); /* This is a platform encoded string */
60*e82f7db8SAndroid Build Coastguard Worker if ( msg != NULL ) {
61*e82f7db8SAndroid Build Coastguard Worker int len;
62*e82f7db8SAndroid Build Coastguard Worker int maxlen;
63*e82f7db8SAndroid Build Coastguard Worker
64*e82f7db8SAndroid Build Coastguard Worker /* Convert this string to UTF8 */
65*e82f7db8SAndroid Build Coastguard Worker len = (int)strlen(msg);
66*e82f7db8SAndroid Build Coastguard Worker maxlen = len+len/2+2; /* Should allow for plenty of room */
67*e82f7db8SAndroid Build Coastguard Worker utf8msg = (jbyte*)jvmtiAllocate(maxlen+1);
68*e82f7db8SAndroid Build Coastguard Worker (void)(gdata->npt->utf8FromPlatform)(gdata->npt->utf,
69*e82f7db8SAndroid Build Coastguard Worker msg, len, utf8msg, maxlen);
70*e82f7db8SAndroid Build Coastguard Worker utf8msg[maxlen] = 0;
71*e82f7db8SAndroid Build Coastguard Worker }
72*e82f7db8SAndroid Build Coastguard Worker if (rv == JDWPTRANSPORT_ERROR_NONE) {
73*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
74*e82f7db8SAndroid Build Coastguard Worker } else if ( msg!=NULL ) {
75*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
76*e82f7db8SAndroid Build Coastguard Worker } else {
77*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport error %d: %s",err, "UNKNOWN"));
78*e82f7db8SAndroid Build Coastguard Worker }
79*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(msg);
80*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(utf8msg);
81*e82f7db8SAndroid Build Coastguard Worker }
82*e82f7db8SAndroid Build Coastguard Worker
83*e82f7db8SAndroid Build Coastguard Worker /* Find OnLoad symbol */
84*e82f7db8SAndroid Build Coastguard Worker static jdwpTransport_OnLoad_t
findTransportOnLoad(void * handle)85*e82f7db8SAndroid Build Coastguard Worker findTransportOnLoad(void *handle)
86*e82f7db8SAndroid Build Coastguard Worker {
87*e82f7db8SAndroid Build Coastguard Worker jdwpTransport_OnLoad_t onLoad;
88*e82f7db8SAndroid Build Coastguard Worker
89*e82f7db8SAndroid Build Coastguard Worker onLoad = (jdwpTransport_OnLoad_t)NULL;
90*e82f7db8SAndroid Build Coastguard Worker if (handle == NULL) {
91*e82f7db8SAndroid Build Coastguard Worker return onLoad;
92*e82f7db8SAndroid Build Coastguard Worker }
93*e82f7db8SAndroid Build Coastguard Worker onLoad = (jdwpTransport_OnLoad_t)
94*e82f7db8SAndroid Build Coastguard Worker dbgsysFindLibraryEntry(handle, "jdwpTransport_OnLoad");
95*e82f7db8SAndroid Build Coastguard Worker return onLoad;
96*e82f7db8SAndroid Build Coastguard Worker }
97*e82f7db8SAndroid Build Coastguard Worker
98*e82f7db8SAndroid Build Coastguard Worker /* Load transport library (directory=="" means do system search) */
99*e82f7db8SAndroid Build Coastguard Worker static void *
loadTransportLibrary(const char * libdir,const char * name)100*e82f7db8SAndroid Build Coastguard Worker loadTransportLibrary(const char *libdir, const char *name)
101*e82f7db8SAndroid Build Coastguard Worker {
102*e82f7db8SAndroid Build Coastguard Worker void *handle;
103*e82f7db8SAndroid Build Coastguard Worker char libname[MAXPATHLEN+2];
104*e82f7db8SAndroid Build Coastguard Worker char buf[MAXPATHLEN*2+100];
105*e82f7db8SAndroid Build Coastguard Worker const char *plibdir;
106*e82f7db8SAndroid Build Coastguard Worker
107*e82f7db8SAndroid Build Coastguard Worker /* Convert libdir from UTF-8 to platform encoding */
108*e82f7db8SAndroid Build Coastguard Worker plibdir = NULL;
109*e82f7db8SAndroid Build Coastguard Worker if ( libdir != NULL ) {
110*e82f7db8SAndroid Build Coastguard Worker int len;
111*e82f7db8SAndroid Build Coastguard Worker
112*e82f7db8SAndroid Build Coastguard Worker len = (int)strlen(libdir);
113*e82f7db8SAndroid Build Coastguard Worker (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
114*e82f7db8SAndroid Build Coastguard Worker (jbyte*)libdir, len, buf, (int)sizeof(buf));
115*e82f7db8SAndroid Build Coastguard Worker plibdir = buf;
116*e82f7db8SAndroid Build Coastguard Worker }
117*e82f7db8SAndroid Build Coastguard Worker
118*e82f7db8SAndroid Build Coastguard Worker /* Construct library name (simple name or full path) */
119*e82f7db8SAndroid Build Coastguard Worker dbgsysBuildLibName(libname, sizeof(libname), plibdir, name);
120*e82f7db8SAndroid Build Coastguard Worker if (strlen(libname) == 0) {
121*e82f7db8SAndroid Build Coastguard Worker return NULL;
122*e82f7db8SAndroid Build Coastguard Worker }
123*e82f7db8SAndroid Build Coastguard Worker
124*e82f7db8SAndroid Build Coastguard Worker /* dlopen (unix) / LoadLibrary (windows) the transport library */
125*e82f7db8SAndroid Build Coastguard Worker handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
126*e82f7db8SAndroid Build Coastguard Worker return handle;
127*e82f7db8SAndroid Build Coastguard Worker }
128*e82f7db8SAndroid Build Coastguard Worker
129*e82f7db8SAndroid Build Coastguard Worker /*
130*e82f7db8SAndroid Build Coastguard Worker * loadTransport() is adapted from loadJVMHelperLib() in
131*e82f7db8SAndroid Build Coastguard Worker * JDK 1.2 javai.c v1.61
132*e82f7db8SAndroid Build Coastguard Worker */
133*e82f7db8SAndroid Build Coastguard Worker static jdwpError
loadTransport(const char * name,jdwpTransportEnv ** transportPtr)134*e82f7db8SAndroid Build Coastguard Worker loadTransport(const char *name, jdwpTransportEnv **transportPtr)
135*e82f7db8SAndroid Build Coastguard Worker {
136*e82f7db8SAndroid Build Coastguard Worker JNIEnv *env;
137*e82f7db8SAndroid Build Coastguard Worker jdwpTransport_OnLoad_t onLoad;
138*e82f7db8SAndroid Build Coastguard Worker void *handle;
139*e82f7db8SAndroid Build Coastguard Worker const char *libdir;
140*e82f7db8SAndroid Build Coastguard Worker
141*e82f7db8SAndroid Build Coastguard Worker /* Make sure library name is not empty */
142*e82f7db8SAndroid Build Coastguard Worker if (name == NULL) {
143*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("library name is empty"));
144*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_LOAD);
145*e82f7db8SAndroid Build Coastguard Worker }
146*e82f7db8SAndroid Build Coastguard Worker
147*e82f7db8SAndroid Build Coastguard Worker /* First, look in sun.boot.library.path. This should find the standard
148*e82f7db8SAndroid Build Coastguard Worker * dt_socket and dt_shmem transport libraries, or any library
149*e82f7db8SAndroid Build Coastguard Worker * that was delivered with the J2SE.
150*e82f7db8SAndroid Build Coastguard Worker * Note: Since 6819213 fixed, Java property sun.boot.library.path can
151*e82f7db8SAndroid Build Coastguard Worker * contain multiple paths. Dll_dir is the first entry and
152*e82f7db8SAndroid Build Coastguard Worker * -Dsun.boot.library.path entries are appended.
153*e82f7db8SAndroid Build Coastguard Worker */
154*e82f7db8SAndroid Build Coastguard Worker libdir = gdata->property_sun_boot_library_path;
155*e82f7db8SAndroid Build Coastguard Worker if (libdir == NULL) {
156*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("Java property sun.boot.library.path is not set"));
157*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_LOAD);
158*e82f7db8SAndroid Build Coastguard Worker }
159*e82f7db8SAndroid Build Coastguard Worker handle = loadTransportLibrary(libdir, name);
160*e82f7db8SAndroid Build Coastguard Worker if (handle == NULL) {
161*e82f7db8SAndroid Build Coastguard Worker /* Second, look along the path used by the native dlopen/LoadLibrary
162*e82f7db8SAndroid Build Coastguard Worker * functions. This should effectively try and load the simple
163*e82f7db8SAndroid Build Coastguard Worker * library name, which will cause the default system library
164*e82f7db8SAndroid Build Coastguard Worker * search technique to happen.
165*e82f7db8SAndroid Build Coastguard Worker * We should only reach here if the transport library wasn't found
166*e82f7db8SAndroid Build Coastguard Worker * in the J2SE directory, e.g. it's a custom transport library
167*e82f7db8SAndroid Build Coastguard Worker * not installed in the J2SE like dt_socket and dt_shmem is.
168*e82f7db8SAndroid Build Coastguard Worker *
169*e82f7db8SAndroid Build Coastguard Worker * Note: Why not use java.library.path? Several reasons:
170*e82f7db8SAndroid Build Coastguard Worker * a) This matches existing agentlib search
171*e82f7db8SAndroid Build Coastguard Worker * b) These are technically not JNI libraries
172*e82f7db8SAndroid Build Coastguard Worker */
173*e82f7db8SAndroid Build Coastguard Worker handle = loadTransportLibrary("", name);
174*e82f7db8SAndroid Build Coastguard Worker }
175*e82f7db8SAndroid Build Coastguard Worker
176*e82f7db8SAndroid Build Coastguard Worker /* See if a library was found with this name */
177*e82f7db8SAndroid Build Coastguard Worker if (handle == NULL) {
178*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport library not found: %s", name));
179*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_LOAD);
180*e82f7db8SAndroid Build Coastguard Worker }
181*e82f7db8SAndroid Build Coastguard Worker
182*e82f7db8SAndroid Build Coastguard Worker /* Find the onLoad address */
183*e82f7db8SAndroid Build Coastguard Worker onLoad = findTransportOnLoad(handle);
184*e82f7db8SAndroid Build Coastguard Worker if (onLoad == NULL) {
185*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport library missing onLoad entry: %s", name));
186*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_LOAD);
187*e82f7db8SAndroid Build Coastguard Worker }
188*e82f7db8SAndroid Build Coastguard Worker
189*e82f7db8SAndroid Build Coastguard Worker /* Get transport interface */
190*e82f7db8SAndroid Build Coastguard Worker env = getEnv();
191*e82f7db8SAndroid Build Coastguard Worker if ( env != NULL ) {
192*e82f7db8SAndroid Build Coastguard Worker jdwpTransportEnv *t;
193*e82f7db8SAndroid Build Coastguard Worker JavaVM *jvm;
194*e82f7db8SAndroid Build Coastguard Worker jint ver;
195*e82f7db8SAndroid Build Coastguard Worker
196*e82f7db8SAndroid Build Coastguard Worker JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
197*e82f7db8SAndroid Build Coastguard Worker ver = (*onLoad)(jvm, &callback, JDWPTRANSPORT_VERSION_1_0, &t);
198*e82f7db8SAndroid Build Coastguard Worker if (ver != JNI_OK) {
199*e82f7db8SAndroid Build Coastguard Worker switch (ver) {
200*e82f7db8SAndroid Build Coastguard Worker case JNI_ENOMEM :
201*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("insufficient memory to complete initialization"));
202*e82f7db8SAndroid Build Coastguard Worker break;
203*e82f7db8SAndroid Build Coastguard Worker
204*e82f7db8SAndroid Build Coastguard Worker case JNI_EVERSION :
205*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport doesn't recognize version %x",
206*e82f7db8SAndroid Build Coastguard Worker JDWPTRANSPORT_VERSION_1_0));
207*e82f7db8SAndroid Build Coastguard Worker break;
208*e82f7db8SAndroid Build Coastguard Worker
209*e82f7db8SAndroid Build Coastguard Worker case JNI_EEXIST :
210*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("transport doesn't support multiple environments"));
211*e82f7db8SAndroid Build Coastguard Worker break;
212*e82f7db8SAndroid Build Coastguard Worker
213*e82f7db8SAndroid Build Coastguard Worker default:
214*e82f7db8SAndroid Build Coastguard Worker ERROR_MESSAGE(("unrecognized error %d from transport", ver));
215*e82f7db8SAndroid Build Coastguard Worker break;
216*e82f7db8SAndroid Build Coastguard Worker }
217*e82f7db8SAndroid Build Coastguard Worker
218*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_INIT);
219*e82f7db8SAndroid Build Coastguard Worker }
220*e82f7db8SAndroid Build Coastguard Worker *transportPtr = t;
221*e82f7db8SAndroid Build Coastguard Worker } else {
222*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_LOAD);
223*e82f7db8SAndroid Build Coastguard Worker }
224*e82f7db8SAndroid Build Coastguard Worker
225*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(NONE);
226*e82f7db8SAndroid Build Coastguard Worker }
227*e82f7db8SAndroid Build Coastguard Worker
228*e82f7db8SAndroid Build Coastguard Worker static void
connectionInitiated(jdwpTransportEnv * t)229*e82f7db8SAndroid Build Coastguard Worker connectionInitiated(jdwpTransportEnv *t)
230*e82f7db8SAndroid Build Coastguard Worker {
231*e82f7db8SAndroid Build Coastguard Worker jint isValid = JNI_FALSE;
232*e82f7db8SAndroid Build Coastguard Worker
233*e82f7db8SAndroid Build Coastguard Worker debugMonitorEnter(listenerLock);
234*e82f7db8SAndroid Build Coastguard Worker
235*e82f7db8SAndroid Build Coastguard Worker /*
236*e82f7db8SAndroid Build Coastguard Worker * Don't allow a connection until initialization is complete
237*e82f7db8SAndroid Build Coastguard Worker */
238*e82f7db8SAndroid Build Coastguard Worker debugInit_waitInitComplete();
239*e82f7db8SAndroid Build Coastguard Worker
240*e82f7db8SAndroid Build Coastguard Worker /* Are we the first transport to get a connection? */
241*e82f7db8SAndroid Build Coastguard Worker
242*e82f7db8SAndroid Build Coastguard Worker if (transport == NULL) {
243*e82f7db8SAndroid Build Coastguard Worker transport = t;
244*e82f7db8SAndroid Build Coastguard Worker isValid = JNI_TRUE;
245*e82f7db8SAndroid Build Coastguard Worker } else {
246*e82f7db8SAndroid Build Coastguard Worker if (transport == t) {
247*e82f7db8SAndroid Build Coastguard Worker /* connected with the same transport as before */
248*e82f7db8SAndroid Build Coastguard Worker isValid = JNI_TRUE;
249*e82f7db8SAndroid Build Coastguard Worker } else {
250*e82f7db8SAndroid Build Coastguard Worker /*
251*e82f7db8SAndroid Build Coastguard Worker * Another transport got a connection - multiple transports
252*e82f7db8SAndroid Build Coastguard Worker * not fully supported yet so shouldn't get here.
253*e82f7db8SAndroid Build Coastguard Worker */
254*e82f7db8SAndroid Build Coastguard Worker (*t)->Close(t);
255*e82f7db8SAndroid Build Coastguard Worker JDI_ASSERT(JNI_FALSE);
256*e82f7db8SAndroid Build Coastguard Worker }
257*e82f7db8SAndroid Build Coastguard Worker }
258*e82f7db8SAndroid Build Coastguard Worker
259*e82f7db8SAndroid Build Coastguard Worker if (isValid) {
260*e82f7db8SAndroid Build Coastguard Worker debugMonitorNotifyAll(listenerLock);
261*e82f7db8SAndroid Build Coastguard Worker }
262*e82f7db8SAndroid Build Coastguard Worker
263*e82f7db8SAndroid Build Coastguard Worker debugMonitorExit(listenerLock);
264*e82f7db8SAndroid Build Coastguard Worker
265*e82f7db8SAndroid Build Coastguard Worker if (isValid) {
266*e82f7db8SAndroid Build Coastguard Worker debugLoop_run();
267*e82f7db8SAndroid Build Coastguard Worker }
268*e82f7db8SAndroid Build Coastguard Worker
269*e82f7db8SAndroid Build Coastguard Worker }
270*e82f7db8SAndroid Build Coastguard Worker
271*e82f7db8SAndroid Build Coastguard Worker /*
272*e82f7db8SAndroid Build Coastguard Worker * Set the transport property (sun.jdwp.listenerAddress) to the
273*e82f7db8SAndroid Build Coastguard Worker * specified value.
274*e82f7db8SAndroid Build Coastguard Worker */
275*e82f7db8SAndroid Build Coastguard Worker static void
setTransportProperty(JNIEnv * env,char * value)276*e82f7db8SAndroid Build Coastguard Worker setTransportProperty(JNIEnv* env, char* value) {
277*e82f7db8SAndroid Build Coastguard Worker char* prop_value = (value == NULL) ? "" : value;
278*e82f7db8SAndroid Build Coastguard Worker setAgentPropertyValue(env, "sun.jdwp.listenerAddress", prop_value);
279*e82f7db8SAndroid Build Coastguard Worker }
280*e82f7db8SAndroid Build Coastguard Worker
281*e82f7db8SAndroid Build Coastguard Worker void
transport_waitForConnection(void)282*e82f7db8SAndroid Build Coastguard Worker transport_waitForConnection(void)
283*e82f7db8SAndroid Build Coastguard Worker {
284*e82f7db8SAndroid Build Coastguard Worker /*
285*e82f7db8SAndroid Build Coastguard Worker * If the VM is suspended on debugger initialization, we wait
286*e82f7db8SAndroid Build Coastguard Worker * for a connection before continuing. This ensures that all
287*e82f7db8SAndroid Build Coastguard Worker * events are delivered to the debugger. (We might as well do this
288*e82f7db8SAndroid Build Coastguard Worker * this since the VM won't continue until a remote debugger attaches
289*e82f7db8SAndroid Build Coastguard Worker * and resumes it.) If not suspending on initialization, we must
290*e82f7db8SAndroid Build Coastguard Worker * just drop any packets (i.e. events) so that the VM can continue
291*e82f7db8SAndroid Build Coastguard Worker * to run. The debugger may not attach until much later.
292*e82f7db8SAndroid Build Coastguard Worker */
293*e82f7db8SAndroid Build Coastguard Worker if (debugInit_suspendOnInit()) {
294*e82f7db8SAndroid Build Coastguard Worker debugMonitorEnter(listenerLock);
295*e82f7db8SAndroid Build Coastguard Worker while (transport == NULL) {
296*e82f7db8SAndroid Build Coastguard Worker debugMonitorWait(listenerLock);
297*e82f7db8SAndroid Build Coastguard Worker }
298*e82f7db8SAndroid Build Coastguard Worker debugMonitorExit(listenerLock);
299*e82f7db8SAndroid Build Coastguard Worker }
300*e82f7db8SAndroid Build Coastguard Worker }
301*e82f7db8SAndroid Build Coastguard Worker
302*e82f7db8SAndroid Build Coastguard Worker static void JNICALL
acceptThread(jvmtiEnv * jvmti_env,JNIEnv * jni_env,void * arg)303*e82f7db8SAndroid Build Coastguard Worker acceptThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
304*e82f7db8SAndroid Build Coastguard Worker {
305*e82f7db8SAndroid Build Coastguard Worker TransportInfo *info;
306*e82f7db8SAndroid Build Coastguard Worker jdwpTransportEnv *t;
307*e82f7db8SAndroid Build Coastguard Worker jdwpTransportError rc;
308*e82f7db8SAndroid Build Coastguard Worker
309*e82f7db8SAndroid Build Coastguard Worker LOG_MISC(("Begin accept thread"));
310*e82f7db8SAndroid Build Coastguard Worker
311*e82f7db8SAndroid Build Coastguard Worker info = (TransportInfo*)(void*)arg;
312*e82f7db8SAndroid Build Coastguard Worker t = info->transport;
313*e82f7db8SAndroid Build Coastguard Worker
314*e82f7db8SAndroid Build Coastguard Worker rc = (*t)->Accept(t, info->timeout, 0);
315*e82f7db8SAndroid Build Coastguard Worker
316*e82f7db8SAndroid Build Coastguard Worker /* System property no longer needed */
317*e82f7db8SAndroid Build Coastguard Worker setTransportProperty(jni_env, NULL);
318*e82f7db8SAndroid Build Coastguard Worker
319*e82f7db8SAndroid Build Coastguard Worker if (rc != JDWPTRANSPORT_ERROR_NONE) {
320*e82f7db8SAndroid Build Coastguard Worker /*
321*e82f7db8SAndroid Build Coastguard Worker * If accept fails it probably means a timeout, or another fatal error
322*e82f7db8SAndroid Build Coastguard Worker * We thus exit the VM after stopping the listener.
323*e82f7db8SAndroid Build Coastguard Worker */
324*e82f7db8SAndroid Build Coastguard Worker printLastError(t, rc);
325*e82f7db8SAndroid Build Coastguard Worker (*t)->StopListening(t);
326*e82f7db8SAndroid Build Coastguard Worker EXIT_ERROR(JVMTI_ERROR_NONE, "could not connect, timeout or fatal error");
327*e82f7db8SAndroid Build Coastguard Worker } else {
328*e82f7db8SAndroid Build Coastguard Worker (*t)->StopListening(t);
329*e82f7db8SAndroid Build Coastguard Worker connectionInitiated(t);
330*e82f7db8SAndroid Build Coastguard Worker }
331*e82f7db8SAndroid Build Coastguard Worker
332*e82f7db8SAndroid Build Coastguard Worker LOG_MISC(("End accept thread"));
333*e82f7db8SAndroid Build Coastguard Worker }
334*e82f7db8SAndroid Build Coastguard Worker
335*e82f7db8SAndroid Build Coastguard Worker static void JNICALL
attachThread(jvmtiEnv * jvmti_env,JNIEnv * jni_env,void * arg)336*e82f7db8SAndroid Build Coastguard Worker attachThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
337*e82f7db8SAndroid Build Coastguard Worker {
338*e82f7db8SAndroid Build Coastguard Worker LOG_MISC(("Begin attach thread"));
339*e82f7db8SAndroid Build Coastguard Worker connectionInitiated((jdwpTransportEnv *)(void*)arg);
340*e82f7db8SAndroid Build Coastguard Worker LOG_MISC(("End attach thread"));
341*e82f7db8SAndroid Build Coastguard Worker }
342*e82f7db8SAndroid Build Coastguard Worker
343*e82f7db8SAndroid Build Coastguard Worker void
transport_initialize(void)344*e82f7db8SAndroid Build Coastguard Worker transport_initialize(void)
345*e82f7db8SAndroid Build Coastguard Worker {
346*e82f7db8SAndroid Build Coastguard Worker transport = NULL;
347*e82f7db8SAndroid Build Coastguard Worker listenerLock = debugMonitorCreate("JDWP Transport Listener Monitor");
348*e82f7db8SAndroid Build Coastguard Worker sendLock = debugMonitorCreate("JDWP Transport Send Monitor");
349*e82f7db8SAndroid Build Coastguard Worker }
350*e82f7db8SAndroid Build Coastguard Worker
351*e82f7db8SAndroid Build Coastguard Worker void
transport_reset(void)352*e82f7db8SAndroid Build Coastguard Worker transport_reset(void)
353*e82f7db8SAndroid Build Coastguard Worker {
354*e82f7db8SAndroid Build Coastguard Worker /*
355*e82f7db8SAndroid Build Coastguard Worker * Reset the transport by closing any listener (will silently fail
356*e82f7db8SAndroid Build Coastguard Worker * with JDWPTRANSPORT_ERROR_ILLEGAL_STATE if not listening), and
357*e82f7db8SAndroid Build Coastguard Worker * closing any connection (will also fail silently if not
358*e82f7db8SAndroid Build Coastguard Worker * connected).
359*e82f7db8SAndroid Build Coastguard Worker *
360*e82f7db8SAndroid Build Coastguard Worker * Note: There's an assumption here that we don't yet support
361*e82f7db8SAndroid Build Coastguard Worker * multiple transports. When we do then we need a clear transition
362*e82f7db8SAndroid Build Coastguard Worker * from the current transport to the new transport.
363*e82f7db8SAndroid Build Coastguard Worker */
364*e82f7db8SAndroid Build Coastguard Worker if (transport != NULL) {
365*e82f7db8SAndroid Build Coastguard Worker setTransportProperty(getEnv(), NULL);
366*e82f7db8SAndroid Build Coastguard Worker (*transport)->StopListening(transport);
367*e82f7db8SAndroid Build Coastguard Worker (*transport)->Close(transport);
368*e82f7db8SAndroid Build Coastguard Worker }
369*e82f7db8SAndroid Build Coastguard Worker }
370*e82f7db8SAndroid Build Coastguard Worker
371*e82f7db8SAndroid Build Coastguard Worker static jdwpError
launch(char * command,char * name,char * address)372*e82f7db8SAndroid Build Coastguard Worker launch(char *command, char *name, char *address)
373*e82f7db8SAndroid Build Coastguard Worker {
374*e82f7db8SAndroid Build Coastguard Worker jint rc;
375*e82f7db8SAndroid Build Coastguard Worker char *buf;
376*e82f7db8SAndroid Build Coastguard Worker char *commandLine;
377*e82f7db8SAndroid Build Coastguard Worker int len;
378*e82f7db8SAndroid Build Coastguard Worker
379*e82f7db8SAndroid Build Coastguard Worker /* Construct complete command line (all in UTF-8) */
380*e82f7db8SAndroid Build Coastguard Worker commandLine = jvmtiAllocate((int)strlen(command) +
381*e82f7db8SAndroid Build Coastguard Worker (int)strlen(name) +
382*e82f7db8SAndroid Build Coastguard Worker (int)strlen(address) + 3);
383*e82f7db8SAndroid Build Coastguard Worker if (commandLine == NULL) {
384*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(OUT_OF_MEMORY);
385*e82f7db8SAndroid Build Coastguard Worker }
386*e82f7db8SAndroid Build Coastguard Worker (void)strcpy(commandLine, command);
387*e82f7db8SAndroid Build Coastguard Worker (void)strcat(commandLine, " ");
388*e82f7db8SAndroid Build Coastguard Worker (void)strcat(commandLine, name);
389*e82f7db8SAndroid Build Coastguard Worker (void)strcat(commandLine, " ");
390*e82f7db8SAndroid Build Coastguard Worker (void)strcat(commandLine, address);
391*e82f7db8SAndroid Build Coastguard Worker
392*e82f7db8SAndroid Build Coastguard Worker /* Convert commandLine from UTF-8 to platform encoding */
393*e82f7db8SAndroid Build Coastguard Worker len = (int)strlen(commandLine);
394*e82f7db8SAndroid Build Coastguard Worker buf = jvmtiAllocate(len*3+3);
395*e82f7db8SAndroid Build Coastguard Worker (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
396*e82f7db8SAndroid Build Coastguard Worker (jbyte*)commandLine, len, buf, len*3+3);
397*e82f7db8SAndroid Build Coastguard Worker
398*e82f7db8SAndroid Build Coastguard Worker /* Exec commandLine */
399*e82f7db8SAndroid Build Coastguard Worker rc = dbgsysExec(buf);
400*e82f7db8SAndroid Build Coastguard Worker
401*e82f7db8SAndroid Build Coastguard Worker /* Free up buffers */
402*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(buf);
403*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(commandLine);
404*e82f7db8SAndroid Build Coastguard Worker
405*e82f7db8SAndroid Build Coastguard Worker /* And non-zero exit status means we had an error */
406*e82f7db8SAndroid Build Coastguard Worker if (rc != SYS_OK) {
407*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(TRANSPORT_INIT);
408*e82f7db8SAndroid Build Coastguard Worker }
409*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(NONE);
410*e82f7db8SAndroid Build Coastguard Worker }
411*e82f7db8SAndroid Build Coastguard Worker
412*e82f7db8SAndroid Build Coastguard Worker jdwpError
transport_startTransport(jboolean isServer,char * name,char * address,long timeout)413*e82f7db8SAndroid Build Coastguard Worker transport_startTransport(jboolean isServer, char *name, char *address,
414*e82f7db8SAndroid Build Coastguard Worker long timeout)
415*e82f7db8SAndroid Build Coastguard Worker {
416*e82f7db8SAndroid Build Coastguard Worker jvmtiStartFunction func;
417*e82f7db8SAndroid Build Coastguard Worker jdwpTransportEnv *trans;
418*e82f7db8SAndroid Build Coastguard Worker char threadName[MAXPATHLEN + 100];
419*e82f7db8SAndroid Build Coastguard Worker jint err;
420*e82f7db8SAndroid Build Coastguard Worker jdwpError serror;
421*e82f7db8SAndroid Build Coastguard Worker
422*e82f7db8SAndroid Build Coastguard Worker /*
423*e82f7db8SAndroid Build Coastguard Worker * If the transport is already loaded then use it
424*e82f7db8SAndroid Build Coastguard Worker * Note: We're assuming here that we don't support multiple
425*e82f7db8SAndroid Build Coastguard Worker * transports - when we do then we need to handle the case
426*e82f7db8SAndroid Build Coastguard Worker * where the transport library only supports a single environment.
427*e82f7db8SAndroid Build Coastguard Worker * That probably means we have a bag a transport environments
428*e82f7db8SAndroid Build Coastguard Worker * to correspond to the transports bag.
429*e82f7db8SAndroid Build Coastguard Worker */
430*e82f7db8SAndroid Build Coastguard Worker if (transport != NULL) {
431*e82f7db8SAndroid Build Coastguard Worker trans = transport;
432*e82f7db8SAndroid Build Coastguard Worker } else {
433*e82f7db8SAndroid Build Coastguard Worker serror = loadTransport(name, &trans);
434*e82f7db8SAndroid Build Coastguard Worker if (serror != JDWP_ERROR(NONE)) {
435*e82f7db8SAndroid Build Coastguard Worker return serror;
436*e82f7db8SAndroid Build Coastguard Worker }
437*e82f7db8SAndroid Build Coastguard Worker }
438*e82f7db8SAndroid Build Coastguard Worker
439*e82f7db8SAndroid Build Coastguard Worker if (isServer) {
440*e82f7db8SAndroid Build Coastguard Worker
441*e82f7db8SAndroid Build Coastguard Worker char *retAddress;
442*e82f7db8SAndroid Build Coastguard Worker char *launchCommand;
443*e82f7db8SAndroid Build Coastguard Worker TransportInfo *info;
444*e82f7db8SAndroid Build Coastguard Worker jvmtiError error;
445*e82f7db8SAndroid Build Coastguard Worker int len;
446*e82f7db8SAndroid Build Coastguard Worker char* prop_value;
447*e82f7db8SAndroid Build Coastguard Worker
448*e82f7db8SAndroid Build Coastguard Worker info = jvmtiAllocate(sizeof(*info));
449*e82f7db8SAndroid Build Coastguard Worker if (info == NULL) {
450*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(OUT_OF_MEMORY);
451*e82f7db8SAndroid Build Coastguard Worker }
452*e82f7db8SAndroid Build Coastguard Worker info->name = jvmtiAllocate((int)strlen(name)+1);
453*e82f7db8SAndroid Build Coastguard Worker (void)strcpy(info->name, name);
454*e82f7db8SAndroid Build Coastguard Worker info->address = NULL;
455*e82f7db8SAndroid Build Coastguard Worker info->timeout = timeout;
456*e82f7db8SAndroid Build Coastguard Worker if (info->name == NULL) {
457*e82f7db8SAndroid Build Coastguard Worker serror = JDWP_ERROR(OUT_OF_MEMORY);
458*e82f7db8SAndroid Build Coastguard Worker goto handleError;
459*e82f7db8SAndroid Build Coastguard Worker }
460*e82f7db8SAndroid Build Coastguard Worker if (address != NULL) {
461*e82f7db8SAndroid Build Coastguard Worker info->address = jvmtiAllocate((int)strlen(address)+1);
462*e82f7db8SAndroid Build Coastguard Worker (void)strcpy(info->address, address);
463*e82f7db8SAndroid Build Coastguard Worker if (info->address == NULL) {
464*e82f7db8SAndroid Build Coastguard Worker serror = JDWP_ERROR(OUT_OF_MEMORY);
465*e82f7db8SAndroid Build Coastguard Worker goto handleError;
466*e82f7db8SAndroid Build Coastguard Worker }
467*e82f7db8SAndroid Build Coastguard Worker }
468*e82f7db8SAndroid Build Coastguard Worker
469*e82f7db8SAndroid Build Coastguard Worker info->transport = trans;
470*e82f7db8SAndroid Build Coastguard Worker
471*e82f7db8SAndroid Build Coastguard Worker err = (*trans)->StartListening(trans, address, &retAddress);
472*e82f7db8SAndroid Build Coastguard Worker if (err != JDWPTRANSPORT_ERROR_NONE) {
473*e82f7db8SAndroid Build Coastguard Worker printLastError(trans, err);
474*e82f7db8SAndroid Build Coastguard Worker serror = JDWP_ERROR(TRANSPORT_INIT);
475*e82f7db8SAndroid Build Coastguard Worker goto handleError;
476*e82f7db8SAndroid Build Coastguard Worker }
477*e82f7db8SAndroid Build Coastguard Worker
478*e82f7db8SAndroid Build Coastguard Worker /*
479*e82f7db8SAndroid Build Coastguard Worker * Record listener address in a system property
480*e82f7db8SAndroid Build Coastguard Worker */
481*e82f7db8SAndroid Build Coastguard Worker len = (int)strlen(name) + (int)strlen(retAddress) + 2; /* ':' and '\0' */
482*e82f7db8SAndroid Build Coastguard Worker prop_value = (char*)jvmtiAllocate(len);
483*e82f7db8SAndroid Build Coastguard Worker strcpy(prop_value, name);
484*e82f7db8SAndroid Build Coastguard Worker strcat(prop_value, ":");
485*e82f7db8SAndroid Build Coastguard Worker strcat(prop_value, retAddress);
486*e82f7db8SAndroid Build Coastguard Worker setTransportProperty(getEnv(), prop_value);
487*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(prop_value);
488*e82f7db8SAndroid Build Coastguard Worker
489*e82f7db8SAndroid Build Coastguard Worker
490*e82f7db8SAndroid Build Coastguard Worker (void)strcpy(threadName, "JDWP Transport Listener: ");
491*e82f7db8SAndroid Build Coastguard Worker (void)strcat(threadName, name);
492*e82f7db8SAndroid Build Coastguard Worker
493*e82f7db8SAndroid Build Coastguard Worker func = &acceptThread;
494*e82f7db8SAndroid Build Coastguard Worker error = spawnNewThread(func, (void*)info, threadName);
495*e82f7db8SAndroid Build Coastguard Worker if (error != JVMTI_ERROR_NONE) {
496*e82f7db8SAndroid Build Coastguard Worker serror = map2jdwpError(error);
497*e82f7db8SAndroid Build Coastguard Worker goto handleError;
498*e82f7db8SAndroid Build Coastguard Worker }
499*e82f7db8SAndroid Build Coastguard Worker
500*e82f7db8SAndroid Build Coastguard Worker launchCommand = debugInit_launchOnInit();
501*e82f7db8SAndroid Build Coastguard Worker if (launchCommand != NULL) {
502*e82f7db8SAndroid Build Coastguard Worker serror = launch(launchCommand, name, retAddress);
503*e82f7db8SAndroid Build Coastguard Worker if (serror != JDWP_ERROR(NONE)) {
504*e82f7db8SAndroid Build Coastguard Worker goto handleError;
505*e82f7db8SAndroid Build Coastguard Worker }
506*e82f7db8SAndroid Build Coastguard Worker } else {
507*e82f7db8SAndroid Build Coastguard Worker if ( ! gdata->quiet ) {
508*e82f7db8SAndroid Build Coastguard Worker TTY_MESSAGE(("Listening for transport %s at address: %s",
509*e82f7db8SAndroid Build Coastguard Worker name, retAddress));
510*e82f7db8SAndroid Build Coastguard Worker }
511*e82f7db8SAndroid Build Coastguard Worker }
512*e82f7db8SAndroid Build Coastguard Worker return JDWP_ERROR(NONE);
513*e82f7db8SAndroid Build Coastguard Worker
514*e82f7db8SAndroid Build Coastguard Worker handleError:
515*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(info->name);
516*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(info->address);
517*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(info);
518*e82f7db8SAndroid Build Coastguard Worker } else {
519*e82f7db8SAndroid Build Coastguard Worker /*
520*e82f7db8SAndroid Build Coastguard Worker * Note that we don't attempt to do a launch here. Launching
521*e82f7db8SAndroid Build Coastguard Worker * is currently supported only in server mode.
522*e82f7db8SAndroid Build Coastguard Worker */
523*e82f7db8SAndroid Build Coastguard Worker
524*e82f7db8SAndroid Build Coastguard Worker /*
525*e82f7db8SAndroid Build Coastguard Worker * If we're connecting to another process, there shouldn't be
526*e82f7db8SAndroid Build Coastguard Worker * any concurrent listens, so its ok if we block here in this
527*e82f7db8SAndroid Build Coastguard Worker * thread, waiting for the attach to finish.
528*e82f7db8SAndroid Build Coastguard Worker */
529*e82f7db8SAndroid Build Coastguard Worker err = (*trans)->Attach(trans, address, timeout, 0);
530*e82f7db8SAndroid Build Coastguard Worker if (err != JDWPTRANSPORT_ERROR_NONE) {
531*e82f7db8SAndroid Build Coastguard Worker printLastError(trans, err);
532*e82f7db8SAndroid Build Coastguard Worker serror = JDWP_ERROR(TRANSPORT_INIT);
533*e82f7db8SAndroid Build Coastguard Worker return serror;
534*e82f7db8SAndroid Build Coastguard Worker }
535*e82f7db8SAndroid Build Coastguard Worker
536*e82f7db8SAndroid Build Coastguard Worker /*
537*e82f7db8SAndroid Build Coastguard Worker * Start the transport loop in a separate thread
538*e82f7db8SAndroid Build Coastguard Worker */
539*e82f7db8SAndroid Build Coastguard Worker (void)strcpy(threadName, "JDWP Transport Listener: ");
540*e82f7db8SAndroid Build Coastguard Worker (void)strcat(threadName, name);
541*e82f7db8SAndroid Build Coastguard Worker
542*e82f7db8SAndroid Build Coastguard Worker func = &attachThread;
543*e82f7db8SAndroid Build Coastguard Worker err = spawnNewThread(func, (void*)trans, threadName);
544*e82f7db8SAndroid Build Coastguard Worker serror = map2jdwpError(err);
545*e82f7db8SAndroid Build Coastguard Worker }
546*e82f7db8SAndroid Build Coastguard Worker return serror;
547*e82f7db8SAndroid Build Coastguard Worker }
548*e82f7db8SAndroid Build Coastguard Worker
549*e82f7db8SAndroid Build Coastguard Worker void
transport_close(void)550*e82f7db8SAndroid Build Coastguard Worker transport_close(void)
551*e82f7db8SAndroid Build Coastguard Worker {
552*e82f7db8SAndroid Build Coastguard Worker if ( transport != NULL ) {
553*e82f7db8SAndroid Build Coastguard Worker (*transport)->Close(transport);
554*e82f7db8SAndroid Build Coastguard Worker }
555*e82f7db8SAndroid Build Coastguard Worker }
556*e82f7db8SAndroid Build Coastguard Worker
557*e82f7db8SAndroid Build Coastguard Worker jboolean
transport_is_open(void)558*e82f7db8SAndroid Build Coastguard Worker transport_is_open(void)
559*e82f7db8SAndroid Build Coastguard Worker {
560*e82f7db8SAndroid Build Coastguard Worker jboolean is_open = JNI_FALSE;
561*e82f7db8SAndroid Build Coastguard Worker
562*e82f7db8SAndroid Build Coastguard Worker if ( transport != NULL ) {
563*e82f7db8SAndroid Build Coastguard Worker is_open = (*transport)->IsOpen(transport);
564*e82f7db8SAndroid Build Coastguard Worker }
565*e82f7db8SAndroid Build Coastguard Worker return is_open;
566*e82f7db8SAndroid Build Coastguard Worker }
567*e82f7db8SAndroid Build Coastguard Worker
568*e82f7db8SAndroid Build Coastguard Worker jint
transport_sendPacket(jdwpPacket * packet)569*e82f7db8SAndroid Build Coastguard Worker transport_sendPacket(jdwpPacket *packet)
570*e82f7db8SAndroid Build Coastguard Worker {
571*e82f7db8SAndroid Build Coastguard Worker jdwpTransportError err = JDWPTRANSPORT_ERROR_NONE;
572*e82f7db8SAndroid Build Coastguard Worker jint rc = 0;
573*e82f7db8SAndroid Build Coastguard Worker
574*e82f7db8SAndroid Build Coastguard Worker if (transport != NULL) {
575*e82f7db8SAndroid Build Coastguard Worker if ( (*transport)->IsOpen(transport) ) {
576*e82f7db8SAndroid Build Coastguard Worker debugMonitorEnter(sendLock);
577*e82f7db8SAndroid Build Coastguard Worker err = (*transport)->WritePacket(transport, packet);
578*e82f7db8SAndroid Build Coastguard Worker debugMonitorExit(sendLock);
579*e82f7db8SAndroid Build Coastguard Worker }
580*e82f7db8SAndroid Build Coastguard Worker if (err != JDWPTRANSPORT_ERROR_NONE) {
581*e82f7db8SAndroid Build Coastguard Worker if ((*transport)->IsOpen(transport)) {
582*e82f7db8SAndroid Build Coastguard Worker printLastError(transport, err);
583*e82f7db8SAndroid Build Coastguard Worker }
584*e82f7db8SAndroid Build Coastguard Worker
585*e82f7db8SAndroid Build Coastguard Worker /*
586*e82f7db8SAndroid Build Coastguard Worker * The users of transport_sendPacket except 0 for
587*e82f7db8SAndroid Build Coastguard Worker * success; non-0 otherwise.
588*e82f7db8SAndroid Build Coastguard Worker */
589*e82f7db8SAndroid Build Coastguard Worker rc = (jint)-1;
590*e82f7db8SAndroid Build Coastguard Worker }
591*e82f7db8SAndroid Build Coastguard Worker
592*e82f7db8SAndroid Build Coastguard Worker } /* else, bit bucket */
593*e82f7db8SAndroid Build Coastguard Worker
594*e82f7db8SAndroid Build Coastguard Worker return rc;
595*e82f7db8SAndroid Build Coastguard Worker }
596*e82f7db8SAndroid Build Coastguard Worker
597*e82f7db8SAndroid Build Coastguard Worker jint
transport_receivePacket(jdwpPacket * packet)598*e82f7db8SAndroid Build Coastguard Worker transport_receivePacket(jdwpPacket *packet)
599*e82f7db8SAndroid Build Coastguard Worker {
600*e82f7db8SAndroid Build Coastguard Worker jdwpTransportError err;
601*e82f7db8SAndroid Build Coastguard Worker
602*e82f7db8SAndroid Build Coastguard Worker err = (*transport)->ReadPacket(transport, packet);
603*e82f7db8SAndroid Build Coastguard Worker if (err != JDWPTRANSPORT_ERROR_NONE) {
604*e82f7db8SAndroid Build Coastguard Worker /*
605*e82f7db8SAndroid Build Coastguard Worker * If transport has been closed return EOF
606*e82f7db8SAndroid Build Coastguard Worker */
607*e82f7db8SAndroid Build Coastguard Worker if (!(*transport)->IsOpen(transport)) {
608*e82f7db8SAndroid Build Coastguard Worker packet->type.cmd.len = 0;
609*e82f7db8SAndroid Build Coastguard Worker return 0;
610*e82f7db8SAndroid Build Coastguard Worker }
611*e82f7db8SAndroid Build Coastguard Worker
612*e82f7db8SAndroid Build Coastguard Worker printLastError(transport, err);
613*e82f7db8SAndroid Build Coastguard Worker
614*e82f7db8SAndroid Build Coastguard Worker /*
615*e82f7db8SAndroid Build Coastguard Worker * Users of transport_receivePacket expect 0 for success,
616*e82f7db8SAndroid Build Coastguard Worker * non-0 otherwise.
617*e82f7db8SAndroid Build Coastguard Worker */
618*e82f7db8SAndroid Build Coastguard Worker return (jint)-1;
619*e82f7db8SAndroid Build Coastguard Worker }
620*e82f7db8SAndroid Build Coastguard Worker return 0;
621*e82f7db8SAndroid Build Coastguard Worker }
622