Search code examples
javabytecode-manipulationjavaagentsjvmtijdi

JDI, Java Byte code instrumentation and Java agents (JWDP, JVMTI)


I am new in the realm of debuggers, instrumentation and JVMTI. So I have few questions about them.

  1. What is the difference between JDI(java debugger interface), JWDP, javaagent and native agent(JVMTI). and where does the java instrumentation API fit in picture.

  2. I am using JDI to intercept exceptions in target java application. but I found out that JDI is not good enough if we talk about how it impacts the performance of target app. I read that most good applications does this with combining JVMTI with byte code instrumentation. But I can't understand how byte code instrumentation can be used with JVMTI. So, how can we do byte code instrumentation along with JVMTI ? any example will be helpful.

  3. Can we instrument both byte code and machine code in java ?

  4. Can static byte code analysis be used along with JVMTI. If yes then how ?

If any question is irrelavent or wrong, let me know.


Solution

  • 1 - I think that this site explains the distinction pretty well: http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/architecture.html - these are basically 3 layers of abstraction built on top of each other, with JVMTI interfacing directly with the running JVM, then JDWP being used as a communication protocol, then JDI as an interface to that remote JVM. You can use a javaagent to perform bytecode instrumentation (orthogonal to the implementation of these 3 things).

    2 - I think that the most performant way to do this would be to instrument all code to add a try/catch in each method to handle an exception - when the exception is caught, you handle it (however you wanted to), then re-throw it. The easiest way to do instrumentation is with the javaagent approach (then using javaassist or asm or whatever). You can instrument bytecode from JVMTI too, but it is much more cumbersome. If you only care about specific exceptions (namely, those that are explicitly thrown, and not those that are thrown internally by the interpreter, like NullPointerException, ArrayIndexOutOfBoundsException etc), then the easiest way to handle these would be to intercept ATHROW instructions (the instruction used to throw an exception). I have no specific experience, but it might be reasonable to create a JVMTI agent that is registered for the Exception event, but I am not sure of its performance (could be just as slow as your JDI approach, could be better).

    3 - No: you can only instrument bytecode running in Java. If you wanted to instrument the machine code, you could try to do that with something like pin, but I think this is probably getting way out of hand for what you are looking for.

    4 - Sure: what sort of static analysis are you interested in? You could certainly use something like soot, and also use JVMTI.