6

I am wondering is it possible to log every exception which occurs on JVM level without changing application code? By every exception I mean caught and uncaught exception... I would like to analyze those logs later and group them by exception type (class) and simply count exceptions by type. I am using HotSpot ;)

Maybe there is smarter why of doing it? For example by any free profiler (YourKit has it but it is not free)? I think that JRockit has exception counter in management console, but don't see anything similar for HotSpot.

asked May 9, 2014 at 9:50
6
  • By default exceptions are sent to stderr; therefore if you redirect stderr you should get your exceptions wherever it is that you redirected. Commented May 9, 2014 at 9:53
  • @fge but then he won't see exceptions which where caught and not printed. Commented May 9, 2014 at 11:19
  • @Absurd-Mind ah yeah, I didn't see that part... Well, short of instrumenting the code I don't see a way to do that Commented May 9, 2014 at 11:27
  • You could change the Throwable constructor to log whenever it is created. I wouldn't do this in production, but to get a better understanding of your application it might be worth it. Commented May 9, 2014 at 11:31
  • 2
    @PeterLawrey An interesting idea. Though not all constructed exceptions are thrown and not all thrown exceptions are constructed :) E.g. HotSpot may throw implicit exceptions (NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException etc.) in a fast-path using a preallocated instance (without creating a new Throwable object). Don't forget to add -XX:-OmitStackTraceInFastThrow to prevent this. Commented May 9, 2014 at 12:39

1 Answer 1

6

I believe there are free tools to do it, but even making your own tool is easy. JVMTI will help.

Here is a simple JVMTI agent I made to trace all exceptions:

#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;
}

To use it, make a shared library (.so) from the given source code, and run Java with -agentpath option:

java -agentpath:libextrace.so MyApplication

This will log all exception class names on stdout. ExceptionCallback also receives a thread, a method and a location where the exception occured, so you can extend the callback to print much more details.

answered May 9, 2014 at 15:02
Sign up to request clarification or add additional context in comments.

2 Comments

I am wondering is it possible to achieve similar functionality with java instrumentation? (java.lang.instrument)
@user1058831 Instrumentation allows you to modify Java bytecode, but not all exceptions come from 'athrow' bytecode. Some of them are thrown by native library code and some are implicitly thrown by JVM. The closest thing you can do by instrumentation is probably Peter's suggestion of modifying Throwable constructor. A the same time JVMTI agent will handle all the cases automatically.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.