【问题标题】:JVMT exception monitorJVMT异常监视器
【发布时间】:2015-08-23 06:54:49
【问题描述】:

如何使用 JVMTI 获取异常堆栈跟踪。我为处理异常编写了简单的代码,但我想要处理异常行数。如何获得这个号码?

#include <jvmti.h>
#include <string.h>
#include "agent.h"

void printStackTrace(JNIEnv* env, jobject exception) {
    jclass throwable_class = (*env).FindClass("java/lang/Throwable");
    jmethodID print_method = (*env).GetMethodID(throwable_class, "printStackTrace", "()V");
    (*env).CallVoidMethod(exception, print_method);
}

void JNICALL ExceptionCallback(jvmtiEnv* jvmti, JNIEnv* env, jthread thread,
                               jmethodID method, jlocation location, jobject exception,
                               jmethodID catch_method, jlocation catch_location) {
    char* class_name;
    jvmtiFrameInfo frames[10000];
    jint count;
    jvmtiError err;

    jclass exception_class = (*env).GetObjectClass(exception);
    (*jvmti).GetClassSignature(exception_class, &class_name, NULL);
    printf("Exception: %s\n", class_name);
    printStackTrace(env, exception);
    err = (*jvmti).GetStackTrace(thread, 0, 10000, (jvmtiFrameInfo *)&frames, &count);
    if (err != JVMTI_ERROR_NONE) {
        printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
        printf("\n");

    }
    printf("Number of records filled: %d\n", count);
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
    jvmtiEnv* jvmti;
    jvmtiEventCallbacks callbacks;
    jvmtiCapabilities capabilities;

    (*vm).GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);

    memset(&capabilities, 0, sizeof(capabilities));
    capabilities.can_generate_exception_events = 1;
    (*jvmti).AddCapabilities(&capabilities);

    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.Exception = ExceptionCallback;
    (*jvmti).SetEventCallbacks(&callbacks, sizeof(callbacks));
    (*jvmti).SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL);

    return 0;
}

【问题讨论】:

    标签: java c++ c jvmti


    【解决方案1】:

    我通过问题解决了。只需添加 capabilities.can_get_line_numbers = 1; 并调用 (*jvmti)->GetLineNumberTable(jvmti, method, &count, &location_table);

    #include <jvmti.h>
    #include <string.h>
    #include <stdio.h>
    
    void printStackTrace(JNIEnv* env, jobject exception) {
        jclass throwable_class = (*env)->FindClass(env, "java/lang/Throwable");
        jmethodID print_method = (*env)->GetMethodID(env, throwable_class, "printStackTrace", "()V");
        (*env)->CallVoidMethod(env, exception, print_method);
    }
    
    void JNICALL ExceptionCallback(jvmtiEnv* jvmti, JNIEnv* env, jthread thread,
                                   jmethodID method, jlocation location, jobject exception,
                                   jmethodID catch_method, jlocation catch_location) {
        char* class_name;
        jclass exception_class = (*env)->GetObjectClass(env, exception);
        (*jvmti)->GetClassSignature(jvmti, exception_class, &class_name, NULL);
    
    
        int count;
        int line_number = 0;
        int i;
        jvmtiLineNumberEntry *location_table;
        (*jvmti)->GetLineNumberTable(jvmti, method, &count, &location_table);
        for (i = 0; i < count - 1; i++)
        {
            jvmtiLineNumberEntry entry1 = location_table[i];
            jvmtiLineNumberEntry entry2 = location_table[i+1];
            if (location >= entry1.start_location && location < entry2.start_location)
            {
                line_number = entry1.line_number;
                break;
            }
        }
        if (location >= location_table[count-1].start_location)
        {
            line_number = location_table[count-1].line_number;
        }
    
        printf("Exception: %s ", class_name);
        printf("%d \n", line_number);
    }
    
    JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
        jvmtiEnv* jvmti;
        jvmtiEventCallbacks callbacks;
        jvmtiCapabilities capabilities;
    
        (*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0);
    
        memset(&capabilities, 0, sizeof(capabilities));
        capabilities.can_generate_exception_events = 1;
        capabilities.can_get_line_numbers = 1;
        (*jvmti)->AddCapabilities(jvmti, &capabilities);
    
        memset(&callbacks, 0, sizeof(callbacks));
        callbacks.Exception = ExceptionCallback;
        (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
        (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL);
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-13
      • 2018-06-14
      相关资源
      最近更新 更多