Ejemplo n.º 1
0
ObjectArray* Java_aura_rt_VM_getStackClasses(Env* env, Class* c, jint skipNum, jint maxDepth) {
    CallStack* callStack = rvmCaptureCallStack(env);
    if (!callStack) return NULL;

    jint index = 0;
    rvmGetNextCallStackMethod(env, callStack, &index); // Skip VM.getStackClasses()
    rvmGetNextCallStackMethod(env, callStack, &index); // Skip caller of VM.getStackClasses()

    while (skipNum > 0) {
        CallStackFrame* frame = rvmGetNextCallStackMethod(env, callStack, &index);
        if (!frame) return NULL;
        skipNum--;
    }

    jint first = index;

    jint depth = 0;
    while (rvmGetNextCallStackMethod(env, callStack, &index)) {
        depth++;
    }
    if (maxDepth > -1 && maxDepth < depth) {
        depth = maxDepth;
    }
    
    ObjectArray* result = rvmNewObjectArray(env, depth, java_lang_Class, NULL, NULL);
    if (!result) return NULL;
    jint i;
    index = first;
    for (i = 0; i < depth; i++) {
        CallStackFrame* frame = rvmGetNextCallStackMethod(env, callStack, &index);
        result->values[i] = (Object*) frame->method->clazz;
    }
    return result;
}
Ejemplo n.º 2
0
ObjectArray* rvmCallStackToStackTraceElements(Env* env, CallStack* callStack, jint first) {
    if (!callStack || callStack->length == 0) {
        return empty_java_lang_StackTraceElement_array;
    }

    // Count the number of methods
    jint index = first;
    jint length = 0;
    while (rvmGetNextCallStackMethod(env, callStack, &index)) {
        length++;
    }

    if (length == 0) {
        return empty_java_lang_StackTraceElement_array;
    }

    ObjectArray* array = rvmNewObjectArray(env, length, java_lang_StackTraceElement, NULL, NULL);
    if (!array) return NULL;

    if (length > 0) {
        jvalue args[4];
        index = first;
        jint i;
        for (i = 0; i < length; i++) {
            Method* m = rvmGetNextCallStackMethod(env, callStack, &index);
            args[0].l = (jobject) m->clazz;
            args[1].l = (jobject) rvmNewStringUTF(env, m->name, -1);
            if (!args[1].l) return NULL;
            args[2].l = (jobject) rvmAttributeGetClassSourceFile(env, m->clazz);
            if (rvmExceptionOccurred(env)) {
                return NULL;
            }
            args[3].i = METHOD_IS_NATIVE(m) ? -2 : -1; // TODO: Line numbers
            array->values[i] = rvmNewObjectA(env, java_lang_StackTraceElement, 
                java_lang_StackTraceElement_constructor, args);
            if (!array->values[i]) return NULL;
        }
    }

    return array;
}
Ejemplo n.º 3
0
ObjectArray* Java_java_lang_Throwable_nativeGetStackTrace(Env* env, Object* thiz, jlong stackState) {
    CallStack* callStack = (CallStack*) LONG_TO_PTR(stackState);
    if (!callStack) {
        return rvmCallStackToStackTraceElements(env, NULL, 0);
    }

    jint index = 0;
    jint first = 0;
    Method* m = rvmGetNextCallStackMethod(env, callStack, &index);
    if (m && m->clazz == java_lang_Throwable && !strcmp(m->name, "nativeFillInStackTrace")) {
        // Skip Throwable.nativeFillInStackTrace()
        rvmGetNextCallStackMethod(env, callStack, &index); // Skip Throwable.fillInStackTrace()
        m = rvmGetNextCallStackMethod(env, callStack, &index);
        first = index;
        if (m) {
            Class* clazz = m->clazz;
            if (clazz == java_lang_Throwable && METHOD_IS_CONSTRUCTOR(m)) {
                // fillInStackTrace() was called from the constructor of Throwable
                // Skip all constructors until the constructor of thiz->clazz
                Class* superclass = java_lang_Object;
                while (m && METHOD_IS_CONSTRUCTOR(m) && clazz != thiz->clazz && clazz->superclass == superclass) {
                    m = rvmGetNextCallStackMethod(env, callStack, &index);
                    if (m && m->clazz != clazz) {
                        superclass = clazz;
                        clazz = m->clazz;
                    }
                    first = index - 1;
                }
                // We're now at the constructor of thiz->clazz which called super(). 
                // Skip all constructors belonging to thiz->clazz to get to the method which created the throwable
                while (m && METHOD_IS_CONSTRUCTOR(m) && clazz == thiz->clazz) {
                    m = rvmGetNextCallStackMethod(env, callStack, &index);
                    if (m) clazz = m->clazz;
                    first = index - 1;
                }
            }
        }
    }

    return rvmCallStackToStackTraceElements(env, callStack, first);
}
Ejemplo n.º 4
0
void rvmThrow(Env* env, Object* e) {
    // TODO: Check that e != NULL?
    if (env->throwable) {
        rvmAbort("rvmThrow() called with env->throwable already set");
    }
    if (IS_TRACE_ENABLED) {
        jlong stackState = rvmGetLongInstanceFieldValue(env, e, stackStateField);
        CallStack* callStack = (CallStack*) LONG_TO_PTR(stackState);
        if (!callStack || callStack->length == 0) {
            TRACEF("Throwing a %s with empty call stack", e->clazz->name);
        } else {
            TRACEF("Throwing a %s. Call stack:", e->clazz->name);
            Method* m;
            jint index = 0;
            while ((m = rvmGetNextCallStackMethod(env, callStack, &index)) != NULL) {
                TRACEF("    %s.%s%s", m->clazz->name, m->name, m->desc);
            }
        }
    }
    env->throwable = e;
}