getsentry / sentry-android-gradle-plugin

Gradle plugin for Sentry Android. Upload proguard, debug files, and more.
https://docs.sentry.io/platforms/android/gradle/
MIT License
143 stars 33 forks source link

VerifyError crash at app start #618

Closed sergiuciuperca closed 10 months ago

sergiuciuperca commented 11 months ago

Integration

sentry-android

Build System

Gradle

AGP Version

8.2.0

Proguard

Disabled

Version

7.1.0

Steps to Reproduce

We are using GooglePlay Services MLKit for face detection. App started to crash after upgrade to sentry v7.1.0 from v6.34.0, and sentry-gradle-plugin from 3.14.0 to 4.1.0.

Maybe something related: https://github.com/getsentry/sentry-android-gradle-plugin/issues/315

Expected Result

No crash

Actual Result

FATAL EXCEPTION: main
    Process: com...**, PID: 32744
    java.lang.VerifyError: Verifier rejected class com.google.mlkit.common.internal.MlKitInitProvider: boolean com.google.mlkit.common.internal.MlKitInitProvider.onCreate() failed to verify: boolean com.google.mlkit.common.internal.MlKitInitProvider.onCreate(): [0x11] register v0 has type Reference: android.content.Context but expected Reference: android.content.ContentProvider (declaration of 'com.google.mlkit.common.internal.MlKitInitProvider' appears in /data/app/~~vuigZRTEGQZcFSdoHPHXhg==/com.circular.pixels.staging-mW1d8RTpCeta2cy9auqPXA==/base.apk!classes17.dex)
     at java.lang.Class.newInstance(Native Method)
     at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
     at androidx.core.app.CoreComponentFactory.instantiateProvider(CoreComponentFactory.java:66)
     at android.app.ActivityThread.installProvider(ActivityThread.java:7754)
     at android.app.ActivityThread.installContentProviders(ActivityThread.java:7276)
     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6983)
     at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
     at android.os.Handler.dispatchMessage(Handler.java:106)
     at android.os.Looper.loopOnce(Looper.java:205)
     at android.os.Looper.loop(Looper.java:294)
     at android.app.ActivityThread.main(ActivityThread.java:8177)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
markushi commented 10 months ago

Hi @sergiuciuperca thanks for reaching out and providing some details around this issue! It looks like this is caused due to app-start instrumentation, which was added in 4.1.0

As a workaround you can disable this specific instrumentation by applying the following config to your app/build.gradle file

sentry {
    tracingInstrumentation {
        appStart {
            enabled = true
        }
    }
}
markushi commented 10 months ago

After some investigation we came to the conclusion that this is due to R8/ProGuard obfuscation being applied onto pre-bundled libraries. The obfuscation makes any bytecode instrumentation on top brittle as it optimizes away common assumptions and rules, e.g. this is no longer true.

On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language). https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.6.1

We're still investigating if there are ways around this, otherwise we'd resort to excluding specific package names from being instrumented.

markushi commented 10 months ago

Hey @sergiuciuperca thanks again for reporting this issue. Good news: A fix shipped with version 4.1.1 of our sentry-android-gradle-plugin.

sergiuciuperca commented 10 months ago

Thank you!