JVMT 异常监视器
JVMT exception monitor
如何使用 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;
}
我按问题解决了。只需要添加 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;
}
如何使用 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;
}
我按问题解决了。只需要添加 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;
}