Re: NegativeArraySizeException merging frames during replaceAsmInstructions
"ebruneton" (via asm Mailing List) <[email protected]> Thu, 17 Mar 2022 11:40:09 +0100
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format...
------------=_1647513611-25320-4
Content-Type: text/plain; charset=UTF-8;
format=flowed
Content-Transfer-Encoding: 8bit
Hi,
The issue is that your instrumentation changes the control flow of a
method, with the addition of a try catch block, but the ClassWriter only
has a COMPUTE_MAXS option. As a result, frames are not recomputed, and
there is a missing frame just before the exception handler. To fix this
you can either use COMPUTE_FRAMES instead of COMPUTE_MAXS, or manually
compute and insert the missing frame before the ATHROW with a
vistFrame(...).
Eric
PS: in your TryCatchWrapper, it is better to visit the try catch block
before its labels, as follows (and as documented in MethodVisitor):
private static class TryCatchWrapper extends AdviceAdapter {
private Label start;
private Label end;
public TryCatchWrapper(MethodVisitor mv, int access, String
name, String descriptor) {
super(ASM9, mv, access, name, descriptor);
}
@Override
protected void onMethodEnter() {
start = new Label();
end = new Label();
visitTryCatchBlock(start, end, end, null);
mv.visitLabel(start);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
visitLabel(end);
visitInsn(ATHROW);
super.visitMaxs(maxStack, maxLocals);
}
}
Le 16/03/2022 20:59, Eirik Bjørsnøs a écrit :
> Hi,
>
> I'm observing a NASE during toByteArray/replaceAsmInstructions while
> instrumenting byte code in a Java agent I'm working on.
>
> I have been able to create a standalone reproducer [1] which provokes
> the following conditions:
>
> 1: One of the methods in the class should incude a Label which returns
> false from the Label.resolve method. This is because the label is a
> forward reference with a relative offset larger than Short.MAX_VALUE,
> hence ASMs hasAsmInstructions is set to true. This seems necessary to
> force a call to replaceAsmInstructions which triggers frame
> processing.
>
> 2: Another method of the class is instrumented with a trycatchblock
> which wraps the body of the method This catch block handler simply
> ATHROWs the Throwable. This seems necessary to create the conditions
> where the frame merge throws NASE.
>
> Here's the stack trace cased by the minimal reproducer:
>
> Exception in thread "main" java.lang.NegativeArraySizeException: -1
> at org.objectweb.asm.Frame.merge(Frame.java:1222)
> at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java:53)
> at org.objectweb.asm.MethodWriter.visitInsn(MethodWriter.java:868)
> at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2213)
> at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514)
> at org.objectweb.asm.ClassReader.accept(ClassReader.java:744)
> at
> org.objectweb.asm.ClassWriter.replaceAsmInstructions(ClassWriter.java:755)
> at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:718)
> at
> com.example.asmnase.ReplaceAsmInstructionsNASE.main(ReplaceAsmInstructionsNASE.java:37)
>
> The following Gist contains the reproducer:
>
> https://gist.github.com/eirbjo/3eb8ca755f2a399ac8e5def6f43439e5
>
> Note that the instrumentation produces valid class files which are
> verified and loaded by the JVM. It's only in the abnormal case of
> large relative forward references that ASM throws this exception. So I
> think the produced byte code is valid and there might be a bug in ASM
> here.
>
> What do you think?
>
> Cheers,
> Eirik.
>
> --
> You receive this message as a subscriber of the [email protected] mailing
> list.
> To unsubscribe: mailto:[email protected]
> For general help: mailto:[email protected]?subject=help
> OW2 mailing lists service home page: http://www.ow2.org/wws
------------=_1647513611-25320-4
Content-Type: text/plain; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
--
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
------------=_1647513611-25320-4--