Menu

#597 Inconsistent stackmap frames at branch target 147

v5.2
open
None
5
2016-05-02
2016-04-06
No

I am attempting to trim my JAR down, but every time I run it after I use ProGuard (5.2.1) it throws the following exception:

Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 147
Exception Details:
  Location:
    coursier/Cache$.validateChecksum(Lcoursier/core/Artifact;Ljava/lang/String;Ljava/io/File;Ljava/util/concurrent/ExecutorService;)Lscalaz/EitherT; @147: new
  Reason:
    Type uninitialized 33 (current frame, stack[0]) is not assignable to 'scalaz/EitherT' (stack map, stack[0])
  Current Frame:
    bci: @108
    flags: { }
    locals: { top, top, 'java/lang/String', top, top, top, 'coursier/core/Artifact', 'scala/Option' }
    stack: { uninitialized 33, uninitialized 33, integer }
  Stackmap Frame:
    bci: @147
    flags: { }
    locals: { top, top, top, top, top, top, top, 'scala/Option' }
    stack: { 'scalaz/EitherT', 'scalaz/EitherT' }
  Bytecode:
    0x0000000: 1904 3a05 2a2b 2db6 00de b601 3112 24bb
    0x0000010: 0033 592b b701 00b9 01b8 0300 c000 653a
    0x0000020: 06bb 00a9 5919 06b6 012b 2cb9 01b7 0200
    0x0000030: 3a07 1907 c100 8d99 002d 1907 c000 8d3a
    0x0000040: 0819 08b6 017c c000 723a 09b2 00d8 bb00
    0x0000050: 5759 2c19 0619 09b7 0124 1905 b601 a13a
    0x0000060: 0aa7 002c b200 cb19 07b6 0150 9900 27b2
    0x0000070: 00d8 b200 d6bb 005f 592c 1906 b601 32b7
    0x0000080: 0125 b601 9db6 01a4 b601 a23a 0a19 0ab7
    0x0000090: 0198 b0bb 0085 5919 07b7 0168 bf       
  Stackmap Table:
    full_frame(@100,{Top,Top,Object[#114],Top,Top,Top,Object[#101],Object[#135]},{Uninitialized[#33],Uninitialized[#33]})
    full_frame(@141,{Top,Top,Top,Top,Top,Top,Top,Top,Top,Top,Object[#175]},{Uninitialized[#33],Uninitialized[#33]})
    full_frame(@147,{Top,Top,Top,Top,Top,Top,Top,Object[#135]},{Object[#169],Object[#169]})

    at com.outr.jefe.repo.Ivy2$Local$.<init>(Ivy2.scala:11)
    at com.outr.jefe.repo.Ivy2$Local$.<clinit>(Ivy2.scala)
    at com.outr.jefe.runner.Repositories.list$lzycompute(Configuration.scala:45)
    at com.outr.jefe.runner.Repositories.list(Configuration.scala:43)
    at com.outr.jefe.runner.Runner$.start(Runner.scala:27)
    at com.outr.jefe.runner.Runner$.delayedEndpoint$com$outr$jefe$runner$Runner$1(Runner.scala:11)
    at com.outr.jefe.runner.Runner$delayedInit$body.apply(Runner.scala:9)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at com.outr.jefe.runner.Runner$.main(Runner.scala:9)
    at com.outr.jefe.runner.Runner.main(Runner.scala)

This is a Scala project and I'm using the following configuration:

-injars      /home/mhicks/projects/open-source/jefe/runner/target/scala-2.11/jefe-runner-assembly-1.0.0.jar
-outjars     /home/mhicks/projects/open-source/jefe/output/runner.jar
-libraryjars <java.home>/lib/rt.jar
-libraryjars <java.home>/lib/jce.jar
-dontwarn scala.**
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}
-keep class * implements org.xml.sax.EntityResolver
-keepclassmembers class * {
    ** MODULE$;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
    long eventCount;
    int  workerCounts;
    int  runControl;
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
    int base;
    int sp;
    int runState;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
    int status;
}
-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue {
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
}
-dontoptimize
-dontobfuscate
-verbose

If I add "-dontshrink" and "-dontpreverify" then everything works, but I don't think ProGuard is doing anything except copying the file at that point.

Related

Bugs: #101
Bugs: #114
Bugs: #135
Bugs: #169
Bugs: #175
Bugs: #33

Discussion

  • Eric Lafortune

    Eric Lafortune - 2016-04-17

    Thanks for your report. The error suggests that ProGuard has computed and added incorrect preverification information for a method. Would it be possible to attach or mail me the compiled class file coursier/Cache$.class (before and after ProGuard has processed it)?

     
  • Eric Lafortune

    Eric Lafortune - 2016-04-17
    • assigned_to: Eric Lafortune
     
  • Matthew D. Hicks

    Eric, I sent you an email at the sourceforge users address. I went ahead and attached them to this ticket as well just in case.

     
  • Matthew D. Hicks

    Any updates on this?

     
  • Eric Lafortune

    Eric Lafortune - 2016-05-02

    ProGuard's preverification step fails to identify a newly created instance of scalaz.EitherT on the stack as uninitialized, after a conditional branch across the initializer (unusual bytecode). A more advanced analyzer on an internal ProGuard branch doesn't have the problem, but backporting it is non-trivial.

    For the time being, you may be able to work around it by restructuring your code slightly, or maybe by using a different Scala compiler.

     

Log in to post a comment.