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 + -
显示快捷键?