2014-05-09 5 views
5

응용 프로그램 코드를 변경하지 않고 JVM 수준에서 발생하는 모든 예외를 기록 할 수 있습니까? 모든 예외에 의해 나는 잡히고 잡히지 않은 예외를 의미한다. 나는 그 로그를 나중에 분석하고 예외 유형 (클래스)별로 그룹화하고 유형별로 예외를 계산하기를 원한다. HotSpot을 사용하고 있습니다.)JVM HotSpot의 Java 예외 카운터

어쩌면 그것을하는 것이 더 똑똑한가요? 예를 들어 무료 프로파일 러 (YourKit에는 있지만 무료는 아닙니다)가 있습니까? JRockit에는 관리 콘솔의 예외 카운터가 있지만 HotSpot에는 아무 것도 보이지 않습니다.

+0

기본적으로 예외는 stderr로 보내집니다. 따라서 stderr를 리디렉션하면 리디렉션되는 곳마다 예외가 발생합니다. – fge

+0

@fge하지만 그는 잡히거나 인쇄되지 않는 예외를 보지 않을 것입니다. –

+0

@ Absurd-Mind ah yeah, 나는 그 부분을 보지 못했습니다 ... 코드를 도구화하는 것이 부족합니다. 그럴 방법이 보이지 않습니다. – fge

답변

5

나는 무료 도구가 있다고 믿지만, 자신 만의 도구를 만드는 것도 쉽습니다. 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은 예외가 발생한 스레드, 메소드 및 위치도 수신하므로 콜백을 확장하여 훨씬 더 자세한 내용을 인쇄 할 수 있습니다.

+0

Java instrumentation과 비슷한 기능을 구현하는 것이 가능한지 궁금합니다. (java.lang.instrument) – user1058831

+2

@ user1058831 Instrumentation에서는 Java 바이트 코드를 수정할 수 있지만 모든 예외가 'athrow'바이트 코드에서 온 것은 아닙니다. 그 중 일부는 네이티브 라이브러리 코드에 의해 던져지고 일부는 JVM에 의해 암시 적으로 던져집니다. Instrumentation으로 할 수있는 가장 가까운 일은 아마도 Peter가'Throwable' 생성자를 수정하는 제안 일 것입니다. 같은 시간에 JVMTI 에이전트가 자동으로 모든 케이스를 처리합니다. – apangin