나는 무료 도구가 있다고 믿지만, 자신 만의 도구를 만드는 것도 쉽습니다. JVMTI 도움이 될 것입니다. 여기
내가 모든 예외 추적하기 위해 만든 간단한 JVMTI 에이전트입니다 :
#include <jni.h>
#include <jvmti.h>
#include <string.h>
#include <stdio.h>
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);
printf("Exception: %s\n", class_name);
}
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;
(*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;
}
이 그것을 사용하기를, 지정된 소스 코드에서 공유 라이브러리 (.so를) 만들고, -agentpath
옵션으로 자바를 실행
를
java -agentpath:libextrace.so MyApplication
이렇게하면 stdout에 모든 예외 클래스 이름이 기록됩니다. ExceptionCallback
은 예외가 발생한 스레드, 메소드 및 위치도 수신하므로 콜백을 확장하여 훨씬 더 자세한 내용을 인쇄 할 수 있습니다.
기본적으로 예외는 stderr로 보내집니다. 따라서 stderr를 리디렉션하면 리디렉션되는 곳마다 예외가 발생합니다. – fge
@fge하지만 그는 잡히거나 인쇄되지 않는 예외를 보지 않을 것입니다. –
@ Absurd-Mind ah yeah, 나는 그 부분을 보지 못했습니다 ... 코드를 도구화하는 것이 부족합니다. 그럴 방법이 보이지 않습니다. – fge