示例#1
0
/*
 * Called once to build the initial prepared class hash table.
 */
void
classTrack_initialize()
{
    JNIEnv *env = getEnv();
    jint classCount;    
    jclass *classes = allLoadedClasses(&classCount);
    jint i;

    if (classes == NULL) {
        ALLOC_ERROR_EXIT();
    }
    table = jdwpClearedAlloc(HASH_SLOT_COUNT * sizeof(KlassNode *));
    if (table == NULL) {
        jdwpFree(classes);
        ALLOC_ERROR_EXIT();
    }
    for (i=0; i<classCount; i++) {
        jclass klass = classes[i];

        /* Filter out unprepared classes (arrays may or
         * may not be marked as prepared) */
        jboolean preped = (classStatus(klass) & JVMDI_CLASS_STATUS_PREPARED) != 0;
        if (preped || isArrayClass(klass)) {
            classTrack_addPreparedClass(env, klass);
        }
        (*env)->DeleteGlobalRef(env, klass);
    }
    jdwpFree(classes);
}    
示例#2
0
/*
 * Add a class to the prepared class hash table.
 * Assumes no duplicates.
 */
void
classTrack_addPreparedClass(JNIEnv *env, jclass klass)
{
    jint slot = hashKlass(klass);
    KlassNode **head = &table[slot];
    KlassNode *node;

    if (assertOn) {
        /* Check this is not a duplicate */
        for (node = *head; node != NULL; node = node->next) {
            if ((*env)->IsSameObject(env, klass, node->klass)) {
                JDI_ASSERT_FAILED("Attempting to insert duplicate class");
                break;
            }
        }
    }
       
    node = jdwpAlloc(sizeof(KlassNode));
    if (node == NULL) {
        ALLOC_ERROR_EXIT();
    }
    if ((node->signature = classSignature(klass)) == NULL) {
        jdwpFree(node);
        ALLOC_ERROR_EXIT();
    }
    if ((node->klass = (*env)->NewWeakGlobalRef(env, klass)) == NULL) {
        jdwpFree(node->signature);
        jdwpFree(node);
        ALLOC_ERROR_EXIT();
    }

    /* Insert the new node */
    node->next = *head;
    *head = node;
}
示例#3
0
/* 
 * Called after class unloads have occurred.  Creates a new hash table
 * of currently loaded prepared classes. 
 * The signatures of classes which were unloaded (not present in the
 * new table) are returned.
 */
struct bag *
classTrack_processUnloads(JNIEnv *env)
{
    KlassNode **newTable = jdwpClearedAlloc(HASH_SLOT_COUNT * sizeof(KlassNode *));
    jint classCount;    
    jclass *classes;
    jint i;
    struct bag *unloadedSignatures;

    if (newTable == NULL) {
        ALLOC_ERROR_EXIT();
    }
    if ((classes = allLoadedClasses(&classCount)) == NULL) {
        jdwpFree(newTable);
        ALLOC_ERROR_EXIT();
    }

    /* Transfer each current class into the new table */
    for (i=0; i<classCount; i++) {
        jclass klass = classes[i];
        transferClass(env, klass, newTable);
        (*env)->DeleteGlobalRef(env, klass);
    }
    jdwpFree(classes);

    /* Delete old table, install new one */
    unloadedSignatures = deleteTable(env, table);
    table = newTable;

    return unloadedSignatures;
}
示例#4
0
void 
outStream_destroy(PacketOutputStream *stream)
{
    struct PacketData *next;

    if (stream->error || !stream->sent) {
        bagEnumerateOver(stream->ids, releaseID, NULL);
    }

    next = stream->packet.type.cmd.data.next;
    while (next != NULL) {
        struct PacketData *p = next;
        next = p->next;
        jdwpFree(p->data);
        jdwpFree(p);
    }
    bagDestroyBag(stream->ids);
}
static jboolean 
children(PacketInputStream *in, PacketOutputStream *out) 
{
     jint error;
     jint i;
     jint threadCount;
     jint groupCount;
     jthread *theThreads;
     jthread *theGroups;
     JNIEnv *env = getEnv();
 
     jthreadGroup group = inStream_readThreadGroupRef(in);
     if (inStream_error(in)) {
         return JNI_TRUE;
     }
 
     error = jvmdi->GetThreadGroupChildren(group,
                                          &threadCount,&theThreads,
                                          &groupCount, &theGroups);
     if (error != JVMDI_ERROR_NONE) {
         outStream_setError(out, error);
         return JNI_TRUE;
     }


     /* Squish out all of the debugger-spawned threads */
     threadCount = filterDebugThreads(theThreads, threadCount);
  
     outStream_writeInt(out, threadCount);
     for (i = 0; i < threadCount; i++) {
         WRITE_GLOBAL_REF(env, out, theThreads[i]);
     }
     outStream_writeInt(out, groupCount);
     for (i = 0; i < groupCount; i++) {
         WRITE_GLOBAL_REF(env, out, theGroups[i]);
     }

     jdwpFree(theGroups);
     jdwpFree(theThreads);
     return JNI_TRUE;
}
示例#6
0
static jint 
writeBytes(PacketOutputStream *stream, void *source, int size)
{
    jbyte *bytes = (jbyte *)source;

    if (stream->error) {
        return stream->error;
    }
    while (size > 0) {
        jint count;
        if (stream->left == 0) {
            jint segSize = MIN(2 * stream->segment->length, MAX_SEGMENT_SIZE);
            jbyte *newSeg = jdwpAlloc(segSize);
            struct PacketData *newHeader = jdwpAlloc(sizeof(*newHeader));
            if ((newSeg == NULL) || (newHeader == NULL)) {
                jdwpFree(newSeg);
                jdwpFree(newHeader);
                stream->error = JVMDI_ERROR_OUT_OF_MEMORY;
                return stream->error;
            }
            newHeader->length = 0;
            newHeader->data = newSeg;
            newHeader->next = NULL;
            stream->segment->next = newHeader;
            stream->segment = newHeader;
            stream->current = newHeader->data;
            stream->left = segSize;
        }
        count = MIN(size, stream->left);
        memcpy(stream->current, bytes, count);
        stream->current += count;
        stream->left -= count;
        stream->segment->length += count;
        size -= count;
        bytes += count;
    }
    return JVMDI_ERROR_NONE;
}
示例#7
0
/*
 * Match the name of a class against a wildcard
 * string pattern.
 */
static jboolean 
patternMatch(jclass clazz, const char *pattern)
{
    jboolean rc;
    char *signature = classSignature(clazz);

    if (signature == NULL) {
        return JNI_FALSE;
    }
    convertSignatureToClassname(signature);
    rc = patternStringMatch(signature, pattern);
    jdwpFree(signature);

    return rc;
}
示例#8
0
/* 
 * Delete a hash table of classes. 
 * The signatures of classes in the table are returned.
 */
static struct bag *
deleteTable(JNIEnv *env, KlassNode *oldTable[])
{
    struct bag *signatures = bagCreateBag(sizeof(char*), 10);
    jint slot;

    if (signatures == NULL) {
        ALLOC_ERROR_EXIT();
    }

    for (slot = 0; slot < HASH_SLOT_COUNT; slot++) {
        KlassNode *node = oldTable[slot];
        
        while (node != NULL) {
            KlassNode *next;
            char **sigSpot;

            /* Add signature to the signature bag */
            sigSpot = bagAdd(signatures);   
            if (sigSpot == NULL) {
                ALLOC_ERROR_EXIT();
            }
            *sigSpot = node->signature;
            
            /* Free weak ref and the node itself */
            (*env)->DeleteWeakGlobalRef(env, node->klass);
            next = node->next;
            jdwpFree(node);

            node = next;
        }
    }
    jdwpFree(oldTable);

    return signatures;
}
static jboolean 
parent(PacketInputStream *in, PacketOutputStream *out) 
{
    JNIEnv *env = getEnv();
    JVMDI_thread_group_info info;

    jthreadGroup group = inStream_readThreadGroupRef(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    threadGroupInfo(group, &info);
    WRITE_GLOBAL_REF(env, out, info.parent);

    jdwpFree(info.name);
    return JNI_TRUE;
}
static jboolean 
name(PacketInputStream *in, PacketOutputStream *out) 
{
    JNIEnv *env = getEnv();
    JVMDI_thread_group_info info;

    jthreadGroup group = inStream_readThreadGroupRef(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    threadGroupInfo(group, &info);
    outStream_writeString(out, info.name);

    (*env)->DeleteGlobalRef(env, info.parent);
    jdwpFree(info.name);
    return JNI_TRUE;
}
示例#11
0
/** 
 * Free up global refs held by the filter. 
 * free things up at the JNI level if needed. 
 */
static jint
clearFilters(HandlerNode *node)
{
    JNIEnv *env = getEnv();
    jint i;
    jint error = JVMDI_ERROR_NONE;
    Filter *filter = FILTERS_ARRAY(node);

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly): {
                jthread threadOnly = filter->u.ThreadOnly.thread;
                if (threadOnly != NULL) { 
                    (*env)->DeleteGlobalRef(env, threadOnly);
                }
                break;
            }
            case JDWP_REQUEST_MODIFIER(LocationOnly): {
                jclass clazz = filter->u.LocationOnly.clazz;
                (*env)->DeleteGlobalRef(env, clazz);
                break;
            }
            case JDWP_REQUEST_MODIFIER(FieldOnly): {
                jclass clazz = filter->u.FieldOnly.clazz;
                (*env)->DeleteGlobalRef(env, clazz);
                break;
            }
            case JDWP_REQUEST_MODIFIER(ExceptionOnly): {
                (*env)->DeleteGlobalRef(env, 
                          filter->u.ExceptionOnly.exception);
                break;
            }
            case JDWP_REQUEST_MODIFIER(InstanceOnly): {
                (*env)->DeleteGlobalRef(env, 
                          filter->u.InstanceOnly.instance);
                break;
            }
            case JDWP_REQUEST_MODIFIER(ClassOnly): {
                (*env)->DeleteGlobalRef(env,
                          filter->u.ClassOnly.clazz);
                break;
            }
            case JDWP_REQUEST_MODIFIER(ClassMatch): {
                jdwpFree(filter->u.ClassMatch.classPattern);
                break;
            }
            case JDWP_REQUEST_MODIFIER(ClassExclude): {
                jdwpFree(filter->u.ClassExclude.classPattern);
                break;
            }
            case JDWP_REQUEST_MODIFIER(Step): {
                jthread thread = filter->u.Step.thread;
                error = stepControl_endStep(thread);
                if (error == JVMDI_ERROR_NONE) {
                    (*env)->DeleteGlobalRef(env, thread);
                }
                break;
            }
        }
    }
    if (error == JVMDI_ERROR_NONE) {
        FILTER_COUNT(node) = 0; /* blast so we don't clear again */
    }

    return error;
}
示例#12
0
int 
dbgsysExec(char *cmdLine)
{
    int i;
    int argc;
    int pid = -1; /* this is the error return value */
    char **argv = NULL;
    char *p;
    char *args;

    /* Skip leading whitespace */
    cmdLine = skipWhitespace(cmdLine);

    args = jdwpAlloc(strlen(cmdLine)+1);
    if (args == NULL) {
        return SYS_NOMEM;
    }
    strcpy(args, cmdLine);

    p = args;

    argc = 0;
    while (*p != '\0') {
        p = skipNonWhitespace(p);
        argc++;
        if (*p == '\0') {
            break;
        }
        p = skipWhitespace(p);
    }

    argv = jdwpAlloc((argc + 1) * sizeof(char *));
    if (argv == 0) {
        jdwpFree(args);
        return SYS_NOMEM;
    }

    for (i = 0, p = args; i < argc; i++) {
        argv[i] = p;
        p = skipNonWhitespace(p);
        *p++ = '\0';
        p = skipWhitespace(p);
    }

    if ((pid = fork()) == 0) {
        /* Child process */
        int i, max_fd;

        /* close everything */
        max_fd = sysconf(_SC_OPEN_MAX);
        for (i = 3; i < max_fd; i++) {
            close(i);
        }

        execvp(argv[0], argv);

        exit(-1);
    }
    jdwpFree(args);
    jdwpFree(argv);
    if (pid < 0) {
        return SYS_ERR;
    } else {
        return SYS_OK;
    }
}