Exemple #1
0
jvalue 
inStream_readValue(PacketInputStream *stream, jbyte *typeKeyPtr)
{
    jvalue value;
    jbyte typeKey = inStream_readByte(stream);
    if (stream->error) {
        value.j = 0L;
        return value;
    }

    if (isObjectTag(typeKey)) {
        value.l = inStream_readObjectRef(stream);
    } else {
        switch (typeKey) {
            case JDWP_TAG(BYTE):
                value.b = inStream_readByte(stream);
                break;
    
            case JDWP_TAG(CHAR):
                value.c = inStream_readChar(stream);
                break;
    
            case JDWP_TAG(FLOAT):
                value.f = inStream_readFloat(stream);
                break;
    
            case JDWP_TAG(DOUBLE):
                value.d = inStream_readDouble(stream);
                break;
    
            case JDWP_TAG(INT):
                value.i = inStream_readInt(stream);
                break;
    
            case JDWP_TAG(LONG):
                value.j = inStream_readLong(stream);
                break;
    
            case JDWP_TAG(SHORT):
                value.s = inStream_readShort(stream);
                break;
    
            case JDWP_TAG(BOOLEAN):
                value.z = inStream_readBoolean(stream);
                break;
            default:
                stream->error = JDWP_ERROR(INVALID_TAG);
                break;
        }
    }
    if (typeKeyPtr) {
        *typeKeyPtr = typeKey;
    }
    return value;
}
/**
 * This is the back-end implementation for disabling
 * (what are at the JDI level) EventRequests.
 */
static jboolean
clearCommand(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;
    jdwpEvent eventType;
    HandlerID handlerID;
    EventIndex ei;

    eventType = inStream_readByte(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    handlerID = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    ei = jdwp2EventIndex(eventType);
    if (ei == 0) {
        /* NOTE: Clear command not yet spec'ed to return INVALID_EVENT_TYPE */
        outStream_setError(out, JDWP_ERROR(INVALID_EVENT_TYPE));
        return JNI_TRUE;
    }

    error = eventHandler_freeByID(ei, handlerID);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }

    return JNI_TRUE;
}
/**
 * Take JDWP "modifiers" (which are JDI explicit filters, like
 * addCountFilter(), and implicit filters, like the LocationOnly
 * filter that goes with breakpoints) and add them as filters
 * (eventFilter) to the HandlerNode (eventHandler).
 */
static jdwpError
readAndSetFilters(JNIEnv *env, PacketInputStream *in, HandlerNode *node,
                  jint filterCount)
{
    int i;
    jdwpError serror = JDWP_ERROR(NONE);

    for (i = 0; i < filterCount; ++i) {

        jbyte modifier;

        modifier = inStream_readByte(in);
        if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
            break;

        switch (modifier) {

            case JDWP_REQUEST_MODIFIER(Conditional): {
                jint exprID;
                exprID = inStream_readInt(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setConditionalFilter(node, i, exprID));
                break;
            }

            case JDWP_REQUEST_MODIFIER(Count): {
                jint count;
                count = inStream_readInt(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setCountFilter(node, i, count));
                break;
            }

            case JDWP_REQUEST_MODIFIER(ThreadOnly): {
                jthread thread;
                thread = inStream_readThreadRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setThreadOnlyFilter(node, i, thread));
                break;
            }

            case JDWP_REQUEST_MODIFIER(LocationOnly): {
                jbyte tag;
                jclass clazz;
                jmethodID method;
                jlocation location;
                tag = inStream_readByte(in); /* not currently used */
                tag = tag; /* To shut up lint */
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                clazz = inStream_readClassRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                method = inStream_readMethodID(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                location = inStream_readLocation(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setLocationOnlyFilter(node, i, clazz, method, location));
                break;
            }

            case JDWP_REQUEST_MODIFIER(FieldOnly): {
                jclass clazz;
                jfieldID field;
                clazz = inStream_readClassRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                field = inStream_readFieldID(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setFieldOnlyFilter(node, i, clazz, field));
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassOnly): {
                jclass clazz;
                clazz = inStream_readClassRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setClassOnlyFilter(node, i, clazz));
                break;
            }

            case JDWP_REQUEST_MODIFIER(ExceptionOnly): {
                jclass exception;
                jboolean caught;
                jboolean uncaught;
                exception = inStream_readClassRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                caught = inStream_readBoolean(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                uncaught = inStream_readBoolean(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setExceptionOnlyFilter(node, i,
                                             exception, caught, uncaught));
                break;
            }

            case JDWP_REQUEST_MODIFIER(InstanceOnly): {
                jobject instance;
                instance = inStream_readObjectRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setInstanceOnlyFilter(node, i, instance));
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassMatch): {
                char *pattern;
                pattern = inStream_readString(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setClassMatchFilter(node, i,
                                                                pattern));
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassExclude): {
                char *pattern;
                pattern = inStream_readString(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                        eventFilter_setClassExcludeFilter(node, i, pattern));
                break;
            }
            case JDWP_REQUEST_MODIFIER(Step): {
                jthread thread;
                jint size;
                jint depth;
                thread = inStream_readThreadRef(env, in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                size = inStream_readInt(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                depth = inStream_readInt(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) )
                    break;
                serror = map2jdwpError(
                      eventFilter_setStepFilter(node, i, thread, size, depth));
                break;
            }
            case JDWP_REQUEST_MODIFIER(SourceNameMatch): {
                char *sourceNamePattern;
                sourceNamePattern = inStream_readString(in);
                if ( (serror = inStream_error(in)) != JDWP_ERROR(NONE) ) {
                    break;
                }
                serror = map2jdwpError(
                        eventFilter_setSourceNameMatchFilter(node, i, sourceNamePattern));
                break;
            }

            default:
                serror = JDWP_ERROR(ILLEGAL_ARGUMENT);
                break;
        }
        if ( serror != JDWP_ERROR(NONE) )
            break;
    }
    return serror;
}
/**
 * This is the back-end implementation for enabling
 * (what are at the JDI level) EventRequests.
 *
 * Allocate the event request handler (eventHandler).
 * Add any filters (explicit or implicit).
 * Install the handler.
 * Return the handlerID which is used to map subsequent
 * events to the EventRequest that created it.
 */
static jboolean
setCommand(PacketInputStream *in, PacketOutputStream *out)
{
    jdwpError serror;
    HandlerNode *node;
    HandlerID requestID = -1;
    jdwpEvent eventType;
    jbyte suspendPolicy;
    jint filterCount;
    EventIndex ei;

    node = NULL;
    eventType = inStream_readByte(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    suspendPolicy = inStream_readByte(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    filterCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    ei = jdwp2EventIndex(eventType);
    if (ei == 0) {
        outStream_setError(out, JDWP_ERROR(INVALID_EVENT_TYPE));
        return JNI_TRUE;
    }

    if (ei == EI_VM_INIT) {
        /*
         * VM is already initialized so there's no need to install a handler
         * for this event. However we need to allocate a requestID to send in
         * the reply to the debugger.
         */
        serror = JDWP_ERROR(NONE);
        requestID = eventHandler_allocHandlerID();
    } else {
        node = eventHandler_alloc(filterCount, ei, suspendPolicy);
        if (node == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
            return JNI_TRUE;
        }
        if (eventType == JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE)) {
            node->needReturnValue = 1;
        } else {
            node->needReturnValue = 0;
        }
        serror = readAndSetFilters(getEnv(), in, node, filterCount);
        if (serror == JDWP_ERROR(NONE)) {
            jvmtiError error;
            error = eventHandler_installExternal(node);
            serror = map2jdwpError(error);
            if (serror == JDWP_ERROR(NONE)) {
                requestID = node->handlerID;
            }
        }
    }

    if (serror == JDWP_ERROR(NONE)) {
        (void)outStream_writeInt(out, requestID);
    } else {
        (void)eventHandler_free(node);
        outStream_setError(out, serror);
    }

    return JNI_TRUE;
}