transport.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 641 行 · 第 1/2 页
C
641 行
/* * @(#)transport.c 1.35 06/10/25 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include "util.h"#include "transport.h"#include "debugLoop.h"#include "sys.h"static jdwpTransportEnv *transport;static jrawMonitorID listenerLock;static jrawMonitorID sendLock;/* * data structure used for passing transport info from thread to thread */typedef struct TransportInfo { char *name; jdwpTransportEnv *transport; char *address; long timeout;} TransportInfo;static struct jdwpTransportCallback callback = {jvmtiAllocate, jvmtiDeallocate};/* * Print the last transport error */static void printLastError(jdwpTransportEnv *t, jdwpTransportError err){ char *msg; jbyte *utf8msg; jdwpTransportError rv; msg = NULL; utf8msg = NULL; rv = (*t)->GetLastError(t, &msg); /* This is a platform encoded string */ if ( msg != NULL ) { int len; int maxlen; /* Convert this string to UTF8 */ len = (int)strlen(msg); maxlen = len+len/2+2; /* Should allow for plenty of room */ utf8msg = (jbyte*)jvmtiAllocate(maxlen+1); (void)(gdata->npt->utf8FromPlatform)(gdata->npt->utf, msg, len, utf8msg, maxlen); utf8msg[maxlen] = 0; } if (rv == JDWPTRANSPORT_ERROR_NONE) { ERROR_MESSAGE(("transport error %d: %s",err, utf8msg)); } else if ( msg!=NULL ) { ERROR_MESSAGE(("transport error %d: %s",err, utf8msg)); } else { ERROR_MESSAGE(("transport error %d: %s",err, "UNKNOWN")); } jvmtiDeallocate(msg); jvmtiDeallocate(utf8msg);}/* Find OnLoad symbol */static jdwpTransport_OnLoad_tfindTransportOnLoad(void *handle){ jdwpTransport_OnLoad_t onLoad; onLoad = (jdwpTransport_OnLoad_t)NULL; if (handle == NULL) { return onLoad; } onLoad = (jdwpTransport_OnLoad_t) dbgsysFindLibraryEntry(handle, "jdwpTransport_OnLoad"); return onLoad;}/* Load transport library (directory=="" means do system search) */static void *loadTransportLibrary(char *libdir, char *name){ void *handle; char libname[MAXPATHLEN+2]; char buf[MAXPATHLEN*2+100]; char *plibdir; /* Convert libdir from UTF-8 to platform encoding */ plibdir = NULL; if ( libdir != NULL ) { int len; len = (int)strlen(libdir); (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf, (jbyte*)libdir, len, buf, (int)sizeof(buf)); plibdir = buf; } /* Construct library name (simple name or full path) */ dbgsysBuildLibName(libname, sizeof(libname), plibdir, name); /* dlopen (unix) / LoadLibrary (windows) the transport library */ handle = dbgsysLoadLibrary(libname); return handle;}/* * loadTransport() is adapted from loadJVMHelperLib() in * JDK 1.2 javai.c v1.61 */static jdwpErrorloadTransport(char *name, jdwpTransportEnv **transportPtr){ JNIEnv *env; jdwpTransport_OnLoad_t onLoad; void *handle; char *libdir; /* Make sure library name is not empty */ if (name == NULL) { ERROR_MESSAGE(("library name is empty")); return JDWP_ERROR(TRANSPORT_LOAD); } /* First, look in sun.boot.library.path. This should find the standard * dt_socket and dt_shmem transport libraries, or any library * that was delivered with the J2SE. * Note: Java property sun.boot.library.path contains a single directory. */ libdir = gdata->property_sun_boot_library_path; if (libdir == NULL) { ERROR_MESSAGE(("Java property sun.boot.library.path is not set")); return JDWP_ERROR(TRANSPORT_LOAD); } handle = loadTransportLibrary(libdir, name); if (handle == NULL) { /* Second, look along the path used by the native dlopen/LoadLibrary * functions. This should effectively try and load the simple * library name, which will cause the default system library * search technique to happen. * We should only reach here if the transport library wasn't found * in the J2SE directory, e.g. it's a custom transport library * not installed in the J2SE like dt_socket and dt_shmem is. * * Note: Why not use java.library.path? Several reasons: * a) This matches existing agentlib search * b) These are technically not JNI libraries */ handle = loadTransportLibrary("", name); } /* See if a library was found with this name */ if (handle == NULL) { ERROR_MESSAGE(("transport library not found: %s", name)); return JDWP_ERROR(TRANSPORT_LOAD); } /* Find the onLoad address */ onLoad = findTransportOnLoad(handle); if (onLoad == NULL) { ERROR_MESSAGE(("transport library missing onLoad entry: %s", name)); return JDWP_ERROR(TRANSPORT_LOAD); } /* Get transport interface */ env = getEnv(); if ( env != NULL ) { jdwpTransportEnv *t; JavaVM *jvm; jint ver; JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm); ver = (*onLoad)(jvm, &callback, JDWPTRANSPORT_VERSION_1_0, &t); if (ver != JNI_OK) { switch (ver) { case JNI_ENOMEM : ERROR_MESSAGE(("insufficient memory to complete initialization")); break; case JNI_EVERSION : ERROR_MESSAGE(("transport doesn't recognize version %x", JDWPTRANSPORT_VERSION_1_0)); break; case JNI_EEXIST : ERROR_MESSAGE(("transport doesn't support multiple environments")); break; default: ERROR_MESSAGE(("unrecognized error %d from transport", ver)); break; } return JDWP_ERROR(TRANSPORT_INIT); } (*t)->_handle = handle; *transportPtr = t; } else { return JDWP_ERROR(TRANSPORT_LOAD); } return JDWP_ERROR(NONE);}static void connectionInitiated(jdwpTransportEnv *t){ jint isValid = JNI_FALSE; debugMonitorEnter(listenerLock); /* * Don't allow a connection until initialization is complete */ debugInit_waitInitComplete(); /* Are we the first transport to get a connection? */ if (transport == NULL) { transport = t; isValid = JNI_TRUE; } else { if (transport == t) { /* connected with the same transport as before */ isValid = JNI_TRUE; } else { /* * Another transport got a connection - multiple transports * not fully supported yet so shouldn't get here. */ (*t)->Close(t); JDI_ASSERT(JNI_FALSE); } } if (isValid) { debugMonitorNotifyAll(listenerLock); } debugMonitorExit(listenerLock); if (isValid) { debugLoop_run(); }}/* * Set the transport property (sun.jdwp.listenerAddress) to the * specified value. */static voidsetTransportProperty(JNIEnv* env, char* value) { char* prop_value = (value == NULL) ? "" : value; setAgentPropertyValue(env, "sun.jdwp.listenerAddress", prop_value);}voidtransport_waitForConnection(void){ /* * If the VM is suspended on debugger initialization, we wait * for a connection before continuing. This ensures that all * events are delivered to the debugger. (We might as well do this * this since the VM won't continue until a remote debugger attaches * and resumes it.) If not suspending on initialization, we must * just drop any packets (i.e. events) so that the VM can continue * to run. The debugger may not attach until much later. */ if (debugInit_suspendOnInit()) { debugMonitorEnter(listenerLock); while (transport == NULL) { debugMonitorWait(listenerLock); } debugMonitorExit(listenerLock); }}static void JNICALLacceptThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg) { TransportInfo *info; jdwpTransportEnv *t; jdwpTransportError rc; LOG_MISC(("Begin accept thread")); info = (TransportInfo*)(void*)arg; t = info->transport; rc = (*t)->Accept(t, info->timeout, 0); /* System property no longer needed */ setTransportProperty(jni_env, NULL); if (rc != JDWPTRANSPORT_ERROR_NONE) { /* * If accept fails it probably means a timeout, or another fatal error * We thus exit the VM after stopping the listener. */ printLastError(t, rc); (*t)->StopListening(t);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?