"Inconsistent stackmap frames at branch target" in funky constructor
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
Hello. I encounter the following exception in my application (a media player) after running ProGuard's optimizer on it:
Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 23 Exception Details: Location: ProGuardBug$Effect$Sepia.<init>(F)V @23: new Reason: Current frame's flags are not assignable to stack map frame's. Current Frame: bci: @8 flags: { flagThisUninit } locals: { uninitializedThis, float } stack: { uninitializedThis, integer } Stackmap Frame: bci: @23 flags: { } locals: { } stack: { uninitializedThis } Bytecode: 0000000: 2a12 0159 44b8 0009 9a00 0f23 0b96 9b00 0000010: 0923 0c95 9e00 0bbb 0007 59b7 000a bf12 0000020: 02b7 0008 b1 Stackmap Table: full_frame(@23,{},{UninitializedThis}) full_frame(@31,{UninitializedThis},{UninitializedThis})
I reduced the problem to a short test case:
public final class ProGuardBug { public static void main(String[] args) { Effect effect; effect = new Effect("invert"); System.out.println(effect.op); effect = new Effect.Sepia(0.5f); System.out.println(effect.op); } static class Effect { final String op; Effect(String op) { this.op = op; } static final class Sepia extends Effect { Sepia(float intensity) { super(createOp(intensity)); } private static String createOp(float intensity) { if (Float.isNaN(intensity) || intensity < 0 || intensity > 1) throw new IllegalArgumentException(); return "sepia"; } } } }
The problem occurs in the "Sepia" constructor that calls a static helper method to do some processing, before invoking the superconstructor. If the optimization method/inlining/unique
is turned off, the problem goes away.
I can work around it, so it's not serious, but I thought I ought to report it.
I forgot to specify, this is Java 9u181 and ProGuard 6.1.0.
Thanks for your detailed report. It turns out to be an edge case for the Java bytecode verifier. We've now fixed it for the upcoming ProGuard 6.1.1.
The fix works. Thank you for the very fast service.