Пример #1
0
static void
notifyTransportError(void) {
    debugMonitorEnter(cmdQueueLock);
    transportError = JNI_TRUE;
    debugMonitorNotify(cmdQueueLock);
    debugMonitorExit(cmdQueueLock);
}
Пример #2
0
jint
transport_sendPacket(jdwpPacket *packet)
{
    jdwpTransportError err = JDWPTRANSPORT_ERROR_NONE;
    jint rc = 0;

    if (transport != NULL) {
        if ( (*transport)->IsOpen(transport) ) {
            debugMonitorEnter(sendLock);
            err = (*transport)->WritePacket(transport, packet);
            debugMonitorExit(sendLock);
        }
        if (err != JDWPTRANSPORT_ERROR_NONE) {
            if ((*transport)->IsOpen(transport)) {
                printLastError(transport, err);
            }

            /*
             * The users of transport_sendPacket except 0 for
             * success; non-0 otherwise.
             */
            rc = (jint)-1;
        }

    } /* else, bit bucket */

    return rc;
}
Пример #3
0
static void
enqueue(jdwpPacket *packet)
{
    struct PacketList *pL;
    struct PacketList *walker;

    pL = jvmtiAllocate((jint)sizeof(struct PacketList));
    if (pL == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"packet list");
    }

    pL->packet = *packet;
    pL->next = NULL;

    debugMonitorEnter(cmdQueueLock);

    if (cmdQueue == NULL) {
        cmdQueue = pL;
        debugMonitorNotify(cmdQueueLock);
    } else {
        walker = (struct PacketList *)cmdQueue;
        while (walker->next != NULL)
            walker = walker->next;

        walker->next = pL;
    }

    debugMonitorExit(cmdQueueLock);
}
Пример #4
0
/* Release tracking of an object by ID */
void 
commonRef_release(JNIEnv *env, jlong id) 
{
    debugMonitorEnter(gdata->refLock); {
        deleteNodeByID(env, id, 1);
    } debugMonitorExit(gdata->refLock);
}
Пример #5
0
/*
 * Given an object ID obtained from the debugger front end, return a
 * strong, global reference to that object (or NULL if the object
 * has been collected). The reference can then be used for JNI and 
 * JVMTI calls. Caller is resposible for deleting the returned reference.
 */
jobject 
commonRef_idToRef(JNIEnv *env, jlong id) 
{
    jobject ref;
    
    ref = NULL;
    debugMonitorEnter(gdata->refLock); {
        RefNode *node;

        node = findNodeByID(env, id);
        if (node != NULL) {
            if (node->isStrong) {
                saveGlobalRef(env, node->ref, &ref);
            } else {
                jobject lref;
                
                lref = JNI_FUNC_PTR(env,NewLocalRef)(env, node->ref);
                if ( lref == NULL ) {
                    /* Object was GC'd shortly after we found the node */
                    deleteNodeByID(env, node->seqNum, ALL_REFS);
                } else {
                    saveGlobalRef(env, node->ref, &ref);
                    JNI_FUNC_PTR(env,DeleteLocalRef)(env, lref);
                }
            }
        }
    } debugMonitorExit(gdata->refLock);
    return ref;
}
Пример #6
0
void 
commonRef_releaseMultiple(JNIEnv *env, jlong id, jint refCount) 
{
    debugMonitorEnter(gdata->refLock); {
        deleteNodeByID(env, id, refCount);
    } debugMonitorExit(gdata->refLock);
}
Пример #7
0
/*
 * Used by either ThreadReferenceImpl.c: resume() or
 * VirtualMachineImpl.c: resume() to resume commandLoop().
 */
void
unblockCommandLoop(void) {
    debugMonitorEnter(blockCommandLoopLock);
    blockCommandLoop = JNI_FALSE;
    debugMonitorNotifyAll(blockCommandLoopLock);
    debugMonitorExit(blockCommandLoopLock);
}
Пример #8
0
/*
 * Given a reference obtained from JNI or JVMTI, return an object
 * id suitable for sending to the debugger front end. The original
 * reference is not deleted. 
 */
jlong 
commonRef_refToID(jobject ref) 
{
    JNIEnv *env;
    RefNode *node;
    jlong id;

    if (ref == NULL) {
        return NULL_OBJECT_ID;
    }
    env = getEnv();

    debugMonitorEnter(refLock);

    node = findNodeByRef(env, ref);
    if (node == NULL) {
        node = newCommonRef(env, ref);
    } else {
        node->count++;
    }

    id = OBJECT_ID(node);

    debugMonitorExit(refLock);

    return id;
}
Пример #9
0
void eventHelper_releaseEvents(void)
{
    debugMonitorEnter(commandQueueLock);
    holdEvents = JNI_FALSE;
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
}
Пример #10
0
/* Prevent garbage collection of an object */
jvmtiError 
commonRef_pin(jlong id) 
{
    JNIEnv *env = getEnv();
    jvmtiError error = JVMTI_ERROR_NONE;
    RefNode *node;

    if (id == NULL_OBJECT_ID) {
        return JNI_FALSE;
    }

    debugMonitorEnter(refLock);

    node = findNodeByID(env, id);
    if (node == NULL) {
        error = JVMTI_ERROR_INVALID_OBJECT;
    } else {
        jobject strongRef = strengthenNode(env, node);
        if (strongRef == NULL) {
            /*
             * Referent has been collected, clean up now.
             */
            error = JVMTI_ERROR_INVALID_OBJECT;
            deleteNodeByID(env, id, ALL_REFS);
        } 
    }

    debugMonitorExit(refLock);

    return error;
}
Пример #11
0
/*
 * Given a reference obtained from JNI or JVMTI, return an object
 * id suitable for sending to the debugger front end. 
 */
jlong 
commonRef_refToID(JNIEnv *env, jobject ref) 
{
    jlong id;

    if (ref == NULL) {
        return NULL_OBJECT_ID;
    }

    id = NULL_OBJECT_ID;
    debugMonitorEnter(gdata->refLock); {
        RefNode *node;

        node = findNodeByRef(env, ref);
        if (node == NULL) {
            node = newCommonRef(env, ref);
            if ( node != NULL ) {
                id = node->seqNum;
            }
        } else {
            id = node->seqNum;
            node->count++;
        }
    } debugMonitorExit(gdata->refLock);
    return id;
}
Пример #12
0
/* Reset the commonRefs usage */
void 
commonRef_reset(JNIEnv *env)
{
    debugMonitorEnter(gdata->refLock); {
        int i;

        for (i = 0; i < gdata->objectsByIDsize; i++) {
            RefNode *node;
            
            node = gdata->objectsByID[i];
            while (node != NULL) {
                RefNode *next;
                
                next = node->next;
                deleteNode(env, node);
                node = next;
            }
            gdata->objectsByID[i] = NULL;
        }
        
        /* Toss entire hash table and re-create a new one */
        jvmtiDeallocate(gdata->objectsByID);
        gdata->objectsByID      = NULL;
        gdata->nextSeqNum       = 1; /* 0 used for error indication */
        initializeObjectsByID(HASH_INIT_SIZE);

    } debugMonitorExit(gdata->refLock);
}
Пример #13
0
static void
enqueueCommand(HelperCommand *command, 
               jboolean wait, jboolean reportingVMDeath) 
{
    static jboolean vmDeathReported = JNI_FALSE;
    CommandQueue *queue = &commandQueue;
    jint size = commandSize(command);
    
    command->done = JNI_FALSE;
    command->waiting = wait;
    command->next = NULL;

    debugMonitorEnter(commandQueueLock);
    while (size + currentQueueSize > maxQueueSize) {
        debugMonitorWait(commandQueueLock);
    }
    log_debugee_location("enqueueCommand(): HelperCommand being processed", NULL, NULL, 0);
    if (vmDeathReported) {
        /* send no more events after VMDeath and don't wait */
        wait = JNI_FALSE;
    } else {
        currentQueueSize += size;

        if (queue->head == NULL) {
            queue->head = command;
        } else {
            queue->tail->next = command;
        }
        queue->tail = command;

        if (reportingVMDeath) {
            vmDeathReported = JNI_TRUE;
        }
    }
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
    
    if (wait) {
        debugMonitorEnter(commandCompleteLock);
        while (!command->done) {
            log_debugee_location("enqueueCommand(): HelperCommand wait", NULL, NULL, 0);
            debugMonitorWait(commandCompleteLock);
        }
        freeCommand(command);
        debugMonitorExit(commandCompleteLock);
    }
}
Пример #14
0
/*
 * We wait for either ThreadReferenceImpl.c: resume() or
 * VirtualMachineImpl.c: resume() to be called.
 */
static void
doBlockCommandLoop(void) {
    debugMonitorEnter(blockCommandLoopLock);
    while (blockCommandLoop == JNI_TRUE) {
        debugMonitorWait(blockCommandLoopLock);
    }
    debugMonitorExit(blockCommandLoopLock);
}
Пример #15
0
/*
 * Wait for all initialization to complete.
 */
void
debugInit_waitInitComplete(void)
{
    debugMonitorEnter(initMonitor);
    while (!initComplete) {
        debugMonitorWait(initMonitor);
    }
    debugMonitorExit(initMonitor);
}
Пример #16
0
void 
eventHelper_reset(jbyte newSessionID)
{
    debugMonitorEnter(commandQueueLock);
    currentSessionID = newSessionID;
    holdEvents = JNI_FALSE;
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
}
Пример #17
0
void 
commonRef_release(jlong id) 
{
    JNIEnv *env = getEnv();

    debugMonitorEnter(refLock);

    deleteNodeByID(env, id, 1);

    debugMonitorExit(refLock);
}
Пример #18
0
void 
commonRef_releaseMultiple(jlong id, jint refCount) 
{
    JNIEnv *env = getEnv();

    debugMonitorEnter(refLock);

    deleteNodeByID(env, id, refCount);

    debugMonitorExit(refLock);
}
Пример #19
0
static void
signalInitComplete(void)
{
    /*
     * Initialization is complete
     */
    LOG_MISC(("signal initialization complete"));
    debugMonitorEnter(initMonitor);
    initComplete = JNI_TRUE;
    debugMonitorNotifyAll(initMonitor);
    debugMonitorExit(initMonitor);
}
Пример #20
0
/*
 * If the command that we are about to execute has a suspend-all
 * policy, then prepare for either ThreadReferenceImpl.c: resume()
 * or VirtualMachineImpl.c: resume() to be called.
 */
static jboolean
needBlockCommandLoop(HelperCommand *cmd) {
    if (cmd->commandKind == COMMAND_REPORT_EVENT_COMPOSITE
    && cmd->u.reportEventComposite.suspendPolicy == JDWP_SUSPEND_POLICY(ALL)) {
        debugMonitorEnter(blockCommandLoopLock);
        blockCommandLoop = JNI_TRUE;
        debugMonitorExit(blockCommandLoopLock);

        return JNI_TRUE;
    }

    return JNI_FALSE;
}
Пример #21
0
static void 
completeCommand(HelperCommand *command) 
{
    if (command->waiting) {
        debugMonitorEnter(commandCompleteLock);
        command->done = JNI_TRUE;
        log_debugee_location("completeCommand(): HelperCommand done waiting", NULL, NULL, 0);
        debugMonitorNotifyAll(commandCompleteLock);
        debugMonitorExit(commandCompleteLock);
    } else {
        freeCommand(command);
    }
}
Пример #22
0
static HelperCommand *
dequeueCommand(void)
{
    HelperCommand *command = NULL;
    CommandQueue *queue = &commandQueue;
    jint size;

    debugMonitorEnter(commandQueueLock);

    while (command == NULL) {
        while (holdEvents || (queue->head == NULL)) {
            debugMonitorWait(commandQueueLock);
        }
    
        JDI_ASSERT(queue->head);
        command = queue->head;
        queue->head = command->next;
        if (queue->tail == command) {
            queue->tail = NULL;
        }
    
        log_debugee_location("dequeueCommand(): command being dequeued", NULL, NULL, 0);
        
        size = commandSize(command);
        /*
         * Immediately close out any commands enqueued from a 
         * previously attached debugger. 
         */
        if (command->sessionID != currentSessionID) {
            log_debugee_location("dequeueCommand(): command session removal", NULL, NULL, 0);
            completeCommand(command);
            command = NULL;
        }

        /*
         * There's room in the queue for more.
         */
        currentQueueSize -= size;
        debugMonitorNotifyAll(commandQueueLock);
    }

    debugMonitorExit(commandQueueLock);

    return command;
}
Пример #23
0
/*
 * Given an object ID obtained from the debugger front end, return a
 * strong, global reference to that object (or NULL if the object
 * has been collected). The reference can then be used for JNI and 
 * JVMTI calls. Caller is resposible for deleting the returned reference.
 */
jobject 
commonRef_idToRef(jlong id) 
{
    JNIEnv *env = getEnv();
    jobject ref = NULL;
    RefNode *node;

    debugMonitorEnter(refLock);

    node = findNodeByID(env, id);
    if (node != NULL) {
        saveGlobalRef(env, node->ref, &ref);
    }

    debugMonitorExit(refLock);

    return ref;
}
Пример #24
0
/* Get rid of RefNodes for objects that no longer exist */
void 
commonRef_compact(void) 
{
    JNIEnv  *env;
    RefNode *node;
    RefNode *prev;
    int      i;

    env = getEnv();
    debugMonitorEnter(gdata->refLock); {
        if ( gdata->objectsByIDsize > 0 ) {
            /* 
             * Walk through the id-based hash table. Detach any nodes
             * for which the ref has been collected. 
             */
            for (i = 0; i < gdata->objectsByIDsize; i++) {
                node = gdata->objectsByID[i];
                prev = NULL;
                while (node != NULL) {
                    /* Has the object been collected? */
                    if ( (!node->isStrong) &&
                          isSameObject(env, node->ref, NULL)) {
                        RefNode *freed;
                        
                        /* Detach from the ID list */
                        if (prev == NULL) {
                            gdata->objectsByID[i] = node->next;
                        } else {
                            prev->next = node->next;
                        }
                        freed = node;
                        node = node->next;
                        deleteNode(env, freed);
                    } else {
                        prev = node;
                        node = node->next;
                    }
                }
            }
        }
    } debugMonitorExit(gdata->refLock);
}
Пример #25
0
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();
    }

}
Пример #26
0
void
transport_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);
    }
}
Пример #27
0
/* Permit garbage collection of an object */
jvmtiError 
commonRef_unpin(jlong id) 
{
    JNIEnv *env = getEnv();
    jvmtiError error = JVMTI_ERROR_NONE;
    RefNode *node;

    debugMonitorEnter(refLock);

    node = findNodeByID(env, id);
    if (node != NULL) {
        jweak weakRef = weakenNode(env, node);
        if (weakRef == NULL) {
            error = JVMTI_ERROR_OUT_OF_MEMORY;
        } 
    }

    debugMonitorExit(refLock);

    return error;
}
Пример #28
0
static jboolean
dequeue(jdwpPacket *packet) {
    struct PacketList *node = NULL;

    debugMonitorEnter(cmdQueueLock);

    while (!transportError && (cmdQueue == NULL)) {
        debugMonitorWait(cmdQueueLock);
    }

    if (cmdQueue != NULL) {
        node = (struct PacketList *)cmdQueue;
        cmdQueue = node->next;
    }
    debugMonitorExit(cmdQueueLock);

    if (node != NULL) {
        *packet = node->packet;
        jvmtiDeallocate(node);
    }
    return (node != NULL);
}
Пример #29
0
void 
commonRef_reset(void)
{
    JNIEnv *env = getEnv();
    int i;
    RefNode *node;

    debugMonitorEnter(refLock);

    for (i = 0; i < CR_HASH_SLOT_COUNT; i++) {
        node = objectsByID[i];
        while (node != NULL) {
            RefNode *temp = node->nextByID;
            deleteNode(env, node);
            node = temp;
        }
        objectsByID[i] = NULL;
        objectsByRef[i] = NULL;
    }
    nextSeqNum = 1;

    debugMonitorExit(refLock);
}
Пример #30
0
void 
commonRef_lock(void) 
{
    debugMonitorEnter(refLock);
}