Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexOutOfBoundsExceptions #65

Open
jdelker opened this issue Oct 31, 2022 · 2 comments
Open

IndexOutOfBoundsExceptions #65

jdelker opened this issue Oct 31, 2022 · 2 comments

Comments

@jdelker
Copy link

jdelker commented Oct 31, 2022

When decompiling particular classes, I sometimes encounter IndexOutOfBoundsExceptions, which manifest in the decompiled code as shown below:

//           
// This method could not be decompiled.          
//           
// Original Bytecode:          
//           
//  [...]      
//           
// The error that occurred was:          
//           
// java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0          
//     at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)          
//     at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)          
//     at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
//     [...]

I tried to look into this myself, but I had to realize, that I just understand too little of the decompilation process to find the root cause.
This problem is present since I started using your marvelous decompiler back in 2018 and also applies to the most recent v0.6.0 release. Due to the fact, that I used the decompiler primarily on licensed legacy code, I never found a way to provide some reproduction steps here.

Well, up to now.
By accident I found another class, that shows the same problem, but is freely available - compiled and in source.
(BTW: There is surely no need to decompile kotlin-stdlib, but as it shows the exact same exception as on the legacy java code, I use it for reproduction here.)

So, please consider the following reproduction steps:

  1. Download Kotlin-Stdlib (https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.20/kotlin-stdlib-1.7.20.jar)
  2. Perform decompile on this JAR (my command was java -jar procyon-decompiler-0.6.0.jar -ln -sl -o /tmp/out kotlin-stdlib-1.7.20.jar
  3. Open /tmp/out/kotlin/SynchronizedLazyImpl.java and find the inline comments of the decompiler logging the java.lang.IndexOutOfBoundsException.

Some observations:

  • There seem to be several inline exceptions in other classes, too, but with other causes. I don't want to overcomplicate things in this issue, so I'm fine with sticking to the IndexOutOfBoundsException for now.
  • While most of the exceptions happen silently (only within the inline-comments of decompiled classes), one IndexOutOfBoundsException is actually thrown in the console (after Decompiling kotlin/text/StringsKt__StringsKt...). But this one seems unrelated to the one in SynchronizedLazyImpl.java.

If you require more details (like the full inline comment), let me know. I didn't want to blow up the description here.

@jdelker
Copy link
Author

jdelker commented Nov 2, 2022

Inline comment found in SynchronizedLazyImpl.java:

//           
// This method could not be decompiled.          
//           
// Original Bytecode:          
//           
//     1: getfield        kotlin/SynchronizedLazyImpl._value:Ljava/lang/Object;          
//     4: astore_1        /* _v1 */          
//     5: aload_1         /* _v1 */          
//     6: getstatic       kotlin/UNINITIALIZED_VALUE.INSTANCE:Lkotlin/UNINITIALIZED_VALUE;          
//     9: if_acmpeq       14          
//    12: aload_1         /* _v1 */          
//    13: areturn                  
//    14: aload_0         /* this */          
//    15: getfield        kotlin/SynchronizedLazyImpl.lock:Ljava/lang/Object;          
//    18: astore_2                 
//    19: aload_2                  
//    20: astore_3                 
//    21: aload_3                  
//    22: monitorenter             
//    23: nop                      
//    24: iconst_0                 
//    25: istore          $i$a$-synchronized-SynchronizedLazyImpl$value$1          
//    27: aload_0         /* this */          
//    28: getfield        kotlin/SynchronizedLazyImpl._value:Ljava/lang/Object;          
//    31: astore          _v2          
//    33: aload           _v2          
//    35: getstatic       kotlin/UNINITIALIZED_VALUE.INSTANCE:Lkotlin/UNINITIALIZED_VALUE;          
//    38: if_acmpeq       46          
//    41: aload           _v2          
//    43: goto            74          
//    46: aload_0         /* this */          
//    47: getfield        kotlin/SynchronizedLazyImpl.initializer:Lkotlin/jvm/functions/Function0;          
//    50: dup                      
//    51: invokestatic    kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V          
//    54: invokeinterface kotlin/jvm/functions/Function0.invoke:()Ljava/lang/Object;          
//    59: astore          typedValue          
//    61: aload_0         /* this */          
//    62: aload           typedValue          
//    64: putfield        kotlin/SynchronizedLazyImpl._value:Ljava/lang/Object;          
//    67: aload_0         /* this */          
//    68: aconst_null              
//    69: putfield        kotlin/SynchronizedLazyImpl.initializer:Lkotlin/jvm/functions/Function0;          
//    72: aload           typedValue          
//    74: nop                      
//    75: astore          null          
//    77: aload_3                  
//    78: monitorexit              
//    79: aload           4          
//    81: goto            91          
//    84: astore          4          
//    86: aload_3                  
//    87: monitorexit              
//    88: aload           4          
//    90: athrow                   
//    91: areturn                  
//    Signature:          
//  ()TT;          
//    StackMapTable: 00 05 FC 00 0E 07 00 05 FF 00 1F 00 06 07 00 02 07 00 05 07 00 05 07 00 05 01 07 00 05 00 00 5B 07 00 05 FF 00 09 00 04 07 00 02 07 00 05 07 00 05 07 00 05 00 01 07 00 41 FF 00 06 00 06 07 00 02 07 00 05 07 00 05 07 00 05 07 00 05 07 00 05 00 01 07 00 05          
//    Exceptions:          
//  Try           Handler          
//  Start  End    Start  End    Type          
//  -----  -----  -----  -----  ----          
//  23     77     84     91     Any          
//  84     86     84     91     Any          
//           
// The error that occurred was:          
//           
// java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0          
//     at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)          
//     at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)          
//     at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)          
//     at java.base/java.util.Objects.checkIndex(Objects.java:372)          
//     at java.base/java.util.ArrayList.remove(ArrayList.java:536)          
//     at com.strobel.assembler.ir.StackMappingVisitor.pop(StackMappingVisitor.java:267)          
//     at com.strobel.assembler.ir.StackMappingVisitor$InstructionAnalyzer.execute(StackMappingVisitor.java:599)          
//     at com.strobel.assembler.ir.StackMappingVisitor$InstructionAnalyzer.visit(StackMappingVisitor.java:398)
//     at com.strobel.decompiler.ast.AstBuilder.performStackAnalysis(AstBuilder.java:2086)
//     at com.strobel.decompiler.ast.AstBuilder.build(AstBuilder.java:108)
//     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:203)
//     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
//     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
//     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
//     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
//     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
//     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
//     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:144)
// 

@jdelker
Copy link
Author

jdelker commented Jul 18, 2024

Friendly reminder, that this is still an ongoing issue and a constant pain when using the decompiled code for debugging things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant