How to measure bytecode to determine when catch clause is executed?

Based on Brett Walker's comment on this question, I was wondering how this could be done.

"If you want to crash the unit test, in the most general sense, when this method executes the catch code, when you have to execute the byte code to tell you when the catch clause is being executed. This is a tricky task. I would not recommend it."

How would I check that some method has executed the catch clause? ( isCatched()

in the example below.

Let's say I have the following class:

public class A {
  public void method() {
    try {
      // some code that may or may not throw an exception
    } catch(Exception e) {
      // do nothing
    }
  }
}

      

And then elsewhere:

public class CatchTester {
  private A a;
  public CatchTester(A a) {
    this.a = a;
  }
  public boolean isCatched() {
    // how to do this?
  }
}

      

0


source to share


2 answers


There are two approaches, both require knowledge of how to manipulate Java byte codes. To make it easier to manipulate byte codes, there are tools like ASM . Then one could plug in a Java Agent or write a custom class loader that changed the bytes of the class as they were loaded into the JVM.



A good example of this approach is https://github.com/google/allocation-instrumenter . The Allocation-Instrumenter modifies the byte codes of the class so that you can register a callback method that is called when the object is allocated. It's not a big part to imagine a similar library for try / catch instrumentation.

+1


source


If you want to determine through Toolkit whether a certain code has been executed, you need to change the code by introducing some kind of logging code that will effectively call a method that records the fact that that code was hit. Then you can check if such an entry exists immediately after the method returns.

While it would be difficult to insert such logging code right at the beginning of each exception handler, the problem arises that, at the byte code level, no distinction between clauses catch

, finally

or try(…)

is made. They all ultimately define exception handlers, some of which may re-throw thrown exceptions. If you want to exclude handlers that throw exceptions, you will need to keep track of every possible path of code, starting from writing the exception handlers, checking if it ends in normal completion, or throws an exception, either hooked, or another newly constructed one.



If you just want to know if any proposal has been implemented catch

, it is much easier. If an method()

exception was thrown during the execution of s but method()

exits normally, that is, the caller does not receive an exception, there must be an exception handler.

+1


source







All Articles