Skip to content

"Stacks have different current sizes" on valid bytecode #509

@Sunderw3k

Description

@Sunderw3k

I'm running proguard on an already obfuscated build, because the optimizer is really good. However the optimizer fails on the bytecode snipped attached below.

This is completely valid bytecode as the instruction at offset 54 can only be reached by either the ifnull at offset 6 where the stack is [aload_1] or from the goto at offset 47 which is directly after an aload_1 on empty stack, so [aload_1].

I'm also not quite sure why it expects 4 variables, as only 3 are ever used and locals is 3.
Those exceptions will also never throw, but that's one thing I was expecting proguard to clean up.

Latest github release version, so 7.8.1

error[1011]: proguard.evaluation.exception.StackGeneralizationException
  --> n/u : a(Ln/c;)V at aload_0 v0
9 |     goto +6
15 |     aload_1 v1
16 |     goto +6
22 |     aload_0 v0
   |     ^^^^^^^^^^ Could not generalize stacks [4:P1:a] and [4:P1:a][15:P1:a] because: "Stacks have different current sizes [1] and [2]".
23 |     getfield #1537
Variables: [P0:P0:a][P1:P1:a][3:M0:a][empty:empty]
Stack: [4:P1:a]

proguard.evaluation.exception.StackGeneralizationException: Could not generalize stacks [4:P1:a] and [4:P1:a][15:P1:a] because: "Stacks have different current sizes [1] and [2]".
	at proguard.evaluation.PartialEvaluator.evaluateSingleInstructionBlock(PartialEvaluator.java:705) ~[proguard.jar:7.8.1]
	at proguard.evaluation.PartialEvaluator.evaluateInstructionBlock(PartialEvaluator.java:624) ~[proguard.jar:7.8.1]
	at proguard.evaluation.PartialEvaluator.evaluateInstructionBlockAndExceptionHandlers(PartialEvaluator.java:599) ~[proguard.jar:7.8.1]
	at proguard.evaluation.PartialEvaluator.visitCodeAttribute0(PartialEvaluator.java:399) ~[proguard.jar:7.8.1]
	at proguard.evaluation.PartialEvaluator.visitCodeAttribute(PartialEvaluator.java:347) ~[proguard.jar:7.8.1]
	at proguard.evaluation.LivenessAnalyzer.visitCodeAttribute(LivenessAnalyzer.java:213) ~[proguard.jar:7.8.1]
	at proguard.optimize.evaluation.VariableOptimizer.visitCodeAttribute(VariableOptimizer.java:103) ~[proguard.jar:7.8.1]
	at proguard.optimize.info.OptimizationCodeAttributeFilter.visitCodeAttribute(OptimizationCodeAttributeFilter.java:82) ~[proguard.jar:7.8.1]
	at proguard.classfile.attribute.visitor.DebugAttributeVisitor.visitCodeAttribute(DebugAttributeVisitor.java:318) ~[proguard.jar:7.8.1]
	at proguard.classfile.attribute.CodeAttribute.accept(CodeAttribute.java:105) ~[proguard.jar:7.8.1]
	at proguard.classfile.ProgramMethod.attributesAccept(ProgramMethod.java:118) ~[proguard.jar:7.8.1]
	at proguard.classfile.attribute.visitor.AllAttributeVisitor.visitProgramMember(AllAttributeVisitor.java:77) ~[proguard.jar:7.8.1]
	at proguard.classfile.visitor.MemberVisitor.visitProgramMethod(MemberVisitor.java:47) ~[proguard.jar:7.8.1]
	at proguard.classfile.ProgramMethod.accept(ProgramMethod.java:113) ~[proguard.jar:7.8.1]
	at proguard.classfile.ProgramClass.methodsAccept(ProgramClass.java:589) ~[proguard.jar:7.8.1]
	at proguard.classfile.visitor.AllMethodVisitor.visitAnyClass(AllMethodVisitor.java:39) ~[proguard.jar:7.8.1]
	at proguard.classfile.visitor.ClassVisitor.visitProgramClass(ClassVisitor.java:35) ~[proguard.jar:7.8.1]
	at proguard.classfile.ProgramClass.accept(ProgramClass.java:491) ~[proguard.jar:7.8.1]
	at proguard.classfile.visitor.ParallelAllClassVisitor$MyThreadedClassVisitor.lambda$submitClassToExecutorService$0(ParallelAllClassVisitor.java:153) ~[proguard.jar:7.8.1]
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.base/java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: java.lang.IllegalArgumentException: Stacks have different current sizes [1] and [2]
	at proguard.evaluation.Stack.generalize(Stack.java:101) ~[proguard.jar:7.8.1]
	at proguard.evaluation.TracedStack.generalize(TracedStack.java:118) ~[proguard.jar:7.8.1]
	at proguard.evaluation.PartialEvaluator.evaluateSingleInstructionBlock(PartialEvaluator.java:703) ~[proguard.jar:7.8.1]
	... 23 more
  public void a(n.c);
    descriptor: (Ln/c;)V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=2
         0: invokestatic  #83                 // Method n/t.b:()[Lo/a;
         3: astore_2
         4: aload_1
         5: aload_2
         6: ifnull        54
         9: invokevirtual #1531               // Method n/c.a:()Z
        12: ifeq          46
        15: goto          22
        18: invokestatic  #120                // Method a:(Ljava/lang/IllegalArgumentException;)Ljava/lang/IllegalArgumentException;
        21: athrow
        22: aload_1
        23: aload_0
        24: getfield      #1533               // Field g:Ln/c;
        27: putfield      #1535               // Field n/c.a:Ln/c;
        30: aload_0
        31: aload_1
        32: putfield      #1533               // Field g:Ln/c;
        35: aload_2
        36: ifnonnull     66
        39: goto          46
        42: invokestatic  #120                // Method a:(Ljava/lang/IllegalArgumentException;)Ljava/lang/IllegalArgumentException;
        45: athrow
        46: aload_1
        47: goto          54
        50: invokestatic  #120                // Method a:(Ljava/lang/IllegalArgumentException;)Ljava/lang/IllegalArgumentException;
        53: athrow
        54: aload_0
        55: getfield      #1537               // Field aa:Ln/c;
        58: putfield      #1535               // Field n/c.a:Ln/c;
        61: aload_0
        62: aload_1
        63: putfield      #1537               // Field aa:Ln/c;
        66: return
      Exception table:
         from    to  target type
             4    15    18   Class java/lang/IllegalArgumentException
             9    39    42   Class java/lang/IllegalArgumentException
            22    47    50   Class java/lang/IllegalArgumentException

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions