Instrumenting after try-catch block in static
initializer may screw exception handler's offsets. This
bug can be reproduced using following code:
public class Main {
private static final Logger log = Logger.getLogger();
public static void main(String args[]) {
}
}
import java.io.File;
public class Logger {
private static File log;
static {
try {
log = new File("/tmp/jfskjfk");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Logger getLogger() {
return new Logger();
}
}
Then instrumenting these with MethodExitInstrumentor
using MethodCallPacth (with a dynamic call).
What makes this strange, is that if the call
Logger.getLogger() is moved from static initializer to
a main method then everything works.
Logged In: YES
user_id=350104
Added a HeadInstrumentor before FieldAssignInstrumentor in
MethodCallInstrumentor. Field assignment messed up exception
handlier. Now field assignment is done before any exception
handler is active.
Logged In: YES
user_id=333539
That fixes the problem only in a specific case. However the
problem still remains. I created a test case to reproduce
this bug in src/test/try_catch_clinit/
The test case fails when instructions are added in between
try-catch block but it works correctly if they are added to
the exception handler code.
java.lang.IncompatibleClassChangeError is thrown when the
test case fails.
The test can be run using:
java -Dn=5 test.try_catch_clinit.FieldAssignTest
Where n specifies the location where the new instructions
are added. Indexes 0-5 add them in between the try-block and
they fail. Indexes bigger than 5 add the instructions to the
exception handler and they succeed.
Logged In: YES
user_id=350104
Did some debugging on this bug and found out a clue
what is going on:
If you dump the instrumented class to file, abd then decompile
it, it provides following Exception instead:
Exception in thread "main" java.lang.ClassFormatError:
Expected class `CONSTANT_Fieldref' at index 31 and got
CONSTANT_Utf8[1]("jeejee")
javap -c decompiles it correctly, but if we use
> java alt.bcel.tools.DeAssembler ./Main.class
Exception above occurs.
We have to possibilities :
a) We have a bug.
b) BCEL has a bug