Status Update
Comments
sg...@google.com <sg...@google.com> #2
Thank you for the report. Will it be possible for you to share the APK which have the issue, so we can take a look at the invalid DEX. You can share it privately with
em...@gmail.com <em...@gmail.com> #3
I have sent the app bundle to
em...@gmail.com <em...@gmail.com> #4
Any news for this issue ? I'm getting to many bug reports from different places in App... But in my device seems to works OK
sg...@google.com <sg...@google.com> #5
Thank you for the app bundle you have shared. I have replied with some comments there by email.
Now, looking at the error again it says
Unresolved Reference: com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature
Could this be that in some code paths the tcpdump_feature
feature is not loaded, but still used?
Do you know which Android versions experience this error? If so have you tried an emulator on these versions?
em...@gmail.com <em...@gmail.com> #6
Thanks for your reply and for your time.
Are you using any additional tools to process the byte code, or are the code from the methods having "non natural loop" coming directly from javac/kotlinc? ->
In fact i am using some Gradle plugins which manipulate Kotlin/Java files before compilation like some "String Obfuscators and Resource Obfuscator", but it makes the job before processing bytecode (i think)
Do you have some more information on which devices/Android version this is happening on? ->
Yesterday i have uploaded new version in Play Store compiled with and seems that those bugs introduced even more. I have uploaded to you email again bundle file for V.18.1.8 (in Production Track) compiled with R8 2.1.3-dev It seems to happens only from Android 7.0 - 8.1 as Firebase Crashlytics says.
Here is one of most happening bug due to Verifier error in V.18.1.8 :
Fatal Exception: java.lang.VerifyError: Verifier rejected class qG8nEeGwwje3A: java.lang.Object qG8nEeGwwje3A.KOFZS8s79TsoyNUjeYewTYz(java.lang.Object) failed to verify: java.lang.Object qG8nEeGwwje3A.KOFZS8s79TsoyNUjeYewTYz(java.lang.Object): [0x5F] cannot access instance field boolean B21DPQ9qoqDoJ1qyjZPttZEUN.p6eP4lBa8qs6446UgyJbQnaYGtA from object of type Unresolved Reference: com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature (declaration of 'qG8nEeGwwje3A' appears in /data/app/com.eakteam.networkmanager.pro-1/base.apk)
I see that recently there is another version of R8 2.1.4-dev but i don't know if it will change things about this (anyway i will always try the latest versions)
Best Regards
sg...@google.com <sg...@google.com> #7
Thanks again for the aab
. I have looked closer at the code, and it turns out that the class qG8nEeGwwje3A
is an R8 generated Kotlin lambda group. In that class R8 collects code for Kotlin lambdas with the same captures. It looks like R8 might merge Kotlin lambdas across feature boundaries, so that a reference to class com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature
ends up in base apk.
The failing code is:
44: 0x57: CheckCast v10, RJcLjsVNfqnfbTbQomMn9l2h
0x59, line 20, locals: [9 -> this]
45: 0x59: IgetObject v10, v9, Field java.lang.Object qG8nEeGwwje3A.hWKgnFVk2gL9tJyarvdMChKp
46: 0x5b: CheckCast v10, DdDdyhOhFNnsmS5KGnZ9kqWU6b
47: 0x5d: IgetObject v10, v10, Field com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature DdDdyhOhFNnsmS5KGnZ9kqWU6b.EvRJyWKZGOpTp4m5ofqKG6
0x5f, line 21, locals: [9 -> this]
48: 0x5f: IputBoolean v8, v10, Field boolean B21DPQ9qoqDoJ1qyjZPttZEUN.p6eP4lBa8qs6446UgyJbQnaYGtA
49: 0x61: ReturnObject v0
(or in smali)
check-cast p1, LRJcLjsVNfqnfbTbQomMn9l2h;
.line 20
iget-object p1, p0, LqG8nEeGwwje3A;->hWKgnFVk2gL9tJyarvdMChKp:Ljava/lang/Object;
check-cast p1, LDdDdyhOhFNnsmS5KGnZ9kqWU6b;
iget-object p1, p1, LDdDdyhOhFNnsmS5KGnZ9kqWU6b;->EvRJyWKZGOpTp4m5ofqKG6:Lcom/eakteam/networkmanager/pro/tcpdump_feature/fragments/tcpdump_feature;
.line 21
iput-boolean v8, p1, LB21DPQ9qoqDoJ1qyjZPttZEUN;->p6eP4lBa8qs6446UgyJbQnaYGtA:Z
return-object v0
and the offending instruction is
48: 0x5f: IputBoolean v8, v10, Field boolean B21DPQ9qoqDoJ1qyjZPttZEUN.p6eP4lBa8qs6446UgyJbQnaYGtA
At this point v10
has an instance of class com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature
and that instance is object of type Unresolved Reference: com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature.
This Kotlin lambda probably should not have been placed in the dex for the base apk.
em...@gmail.com <em...@gmail.com> #8
Thank you so much for your deep investigation. So is there something that i can do or it is R8 bug ? The project is quite large and have to many lambda use cases and many complicated logic.
So will wait for an update to R8 ?
Update: Also, i have replied in the email address.
Thanks for your time !
sg...@google.com <sg...@google.com> #9
I have a tentative fix, and an R8 jar
is attached. It is a build of version 2.1.5-dev with the following patch:
index 8fee6c567..af2093a21 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -238,6 +238,10 @@ public final class LambdaMerger {
.sorted((a, b) -> a.type.slowCompareTo(b.type)) // Ensure stable ordering.
.forEachOrdered(
lambda -> {
+ if (appView.options().featureSplitConfiguration != null &&
+ appView.options().featureSplitConfiguration.isInFeature(lambda)) {
+ return;
+ }
try {
LambdaGroupId id =
KotlinLambdaGroupIdFactory.create(kotlin, lambda, appView.options());
To build with that version:
buildscript {
dependencies {
classpath files($PATH_TO_R8_JAR) // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
em...@gmail.com <em...@gmail.com> #10
I used it and also uploaded an App version to Beta also to be able to get as much info as i can about crash reports from my Beta testers.
The version compiled by this custom R8 is 18.2.3 (and i have uploaded the bundle to your email)
Also, as i said in
Anyway, i will wait for any crash related to this issue and will report back here if it is still happening using this version of R8....
sg...@google.com <sg...@google.com> #11
Thanks to trying out the patch! I was aware that you mentioned that you indicated Android 7.0 - 8.1 in VerifictionError
.
sg...@google.com <sg...@google.com> #12
I finally managed to reproduce the VerificationError
locally. As the reporter already mentioned this is only a VerificationError
on Android 7.0 - 8.1. On all other versions we are testing on the code runs fine.
The reproduction requires a feature split is as follows:
The base contains the following code where Base
is captured in a lambda (passed to printInt
).
fun printInt(l: () -> Int ) = println(l())
open class Base(@JvmField var x: Int, @JvmField var y: Int)
fun main(args: Array<String>) {
val base = Base(args.size + 1, args.size + 2)
printInt { base.x }
printInt { base.y }
}
And the feature contains this code where Feature
extends Base
and is a capture in a lambda.
class Feature(x: Int, y: Int) : Base(x, y)
fun feature(i: Int) {
val f = Feature(i, i + 1)
printInt { f.x }
printInt { f.y }
}
When this is compiled the lambdas from the base and the lambdas from the feature are both added to a lambda group which is placed in the base.
The lambda group invoke
contains this for the first lambda from the feature:
8: 0x0d: IgetObject v0, v2, Field java.lang.Object com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c.$capture$0
9: 0x0f: CheckCast v0, com.android.tools.r8.kotlin.lambda.b148525512.Feature
10: 0x11: Iget v0, v0, Field int com.android.tools.r8.kotlin.lambda.b148525512.Base.y
0x13, line 2, locals: [2 -> this]
11: 0x13: InvokeStatic { v0 } Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
12: 0x16: MoveResultObject v0
13: 0x17: ReturnObject v0
Which cause the VerificationError
:
java.lang.VerifyError: Verifier rejected class com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c: java.lang.Object com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c.invoke() failed to verify: java.lang.Object com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c.invoke(): [0x11] cannot access instance field int com.android.tools.r8.kotlin.lambda.b148525512.Base.y from object of type Unresolved Reference: com.android.tools.r8.kotlin.lambda.b148525512.Feature (declaration of 'com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c' appears in /tmp/junit8694733721787468186/junit10876155525460741592/out.zip) at com.android.tools.r8.kotlin.lambda.b148525512.BaseKt.main()
If the @JvmField
annotation is removed the VerificationError
_oes away, as the field access turns into a virtual invoke of the getter.
17: 0x1c: IgetObject v0, v2, Field java.lang.Object com.android.tools.r8.kotlin.lambda.b148525512.-$$LambdaGroup$ks$fSoYVxbxeJxmZ1HdRAkuBp7sD8c.$capture$0
18: 0x1e: CheckCast v0, com.android.tools.r8.kotlin.lambda.b148525512.Feature
19: 0x20: InvokeVirtual { v0 } Lcom/android/tools/r8/kotlin/lambda/b148525512/Base;->getX()I
20: 0x23: MoveResult v0
0x24, line 5, locals: [2 -> this]
21: 0x24: InvokeStatic { v0 } Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
22: 0x27: MoveResultObject v0
23: 0x28: ReturnObject v0
em...@gmail.com <em...@gmail.com> #13
That's Great !!!
Thank you for your time, please if you can, let me know as soon as it will be ready to use.
sg...@google.com <sg...@google.com>
em...@gmail.com <em...@gmail.com> #14
Thanks for the fix ! I can confirm that the issue is solved with custom R8 that i have tried. But to be sure, you said that it will be fixes in next R8 2.1.x-dev release, so just to be really sure before using it in Production does the latest version 2.1.6-dev contains the fix, or should wait and use the custom version still for the moment ?
OK, it contains it...
ch...@google.com <ch...@google.com> #15
Yes, the fix is available in 2.0.30 and 2.1.6-dev.
Description
Build #AI-193.5233.102.40.6137316, built on January 15, 2020
Runtime version: 1.8.0_212-release-1586-b04 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1994M
Cores: 4
Registry: ide.new.welcome.screen.force=true
Non-Bundled Plugins:
Kotlin 1.3.61
SDK 29
AS Canary 9
I am testing it on multi module app (on demand feature modules) and since v.2.1.2-dev it is throwing this crash :
Fatal Exception: java.lang.VerifyError: Verifier rejected class lVxFwxVBcpNcTd: java.lang.Object lVxFwxVBcpNcTd.nvWUHPf4yZeDhJS8J(java.lang.Object) failed to verify: java.lang.Object lVxFwxVBcpNcTd.nvWUHPf4yZeDhJS8J(java.lang.Object): [0x5F] cannot access instance field boolean evSF1GbQyBLWLkfhHl0angDgt.Hai8bcCnYy from object of type Unresolved Reference: com.eakteam.networkmanager.pro.tcpdump_feature.fragments.tcpdump_feature (declaration of 'lVxFwxVBcpNcTd' appears in base.apk)
Currently i am testing V. 2.1.3-dev to see if it is happening to it too...