Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

coreLibraryDesugaring breaks Sentry #476

Closed
PaulWoitaschek opened this issue Jul 2, 2020 · 14 comments
Closed

coreLibraryDesugaring breaks Sentry #476

PaulWoitaschek opened this issue Jul 2, 2020 · 14 comments
Labels
bug Something isn't working

Comments

@PaulWoitaschek
Copy link

Enabling coreLibraryDesugaring is incompatible with sentry 2.2.0

To reproduce this, add coreLibraryDesugaring to your application and now no events will be sent.

Here is an example project that demonstrates the issue: (it's the official sample)
PaulWoitaschek@167cd61

Just install it to your device in release mode:
./gradlew sentry-sample:installRelease

Click on Capture exception
And you'll see the stacktrace in your log:

2020-07-02 09:33:03.475 16774-16800/? E/Sentry: Event submission failed: 39ec87a940ff4d5fb47a138fc11c0764
    java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
        at com.google.gson.internal.$Gson$Types.getGenericSupertype(Unknown Source:40)
        at com.google.gson.internal.$Gson$Types.getSupertype(Unknown Source:20)
        at com.google.gson.internal.$Gson$Types.getMapKeyAndValueTypes(Unknown Source:20)
        at com.google.gson.internal.bind.MapTypeAdapterFactory.create(Unknown Source:22)
        at com.google.gson.Gson.getDelegateAdapter(Unknown Source:35)
        at com.google.gson.internal.bind.TreeTypeAdapter.delegate(Unknown Source:11)
        at com.google.gson.internal.bind.TreeTypeAdapter.write(Unknown Source:4)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(Unknown Source:34)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(Unknown Source:28)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(Unknown Source:42)
        at io.sentry.android.core.UnknownPropertiesTypeAdapterFactory$UnknownPropertiesTypeAdapter.write(Unknown Source:2)
        at io.sentry.android.core.UnknownPropertiesTypeAdapterFactory$UnknownPropertiesTypeAdapter.write(Unknown Source:2)
        at com.google.gson.Gson.toJson(Unknown Source:34)
        at com.google.gson.Gson.toJson(Unknown Source:8)
        at io.sentry.android.core.AndroidSerializer.serialize(Unknown Source:14)
        at io.sentry.core.transport.HttpTransport.send(Unknown Source:29)
        at io.sentry.core.transport.AsyncConnection$EventSender.flush(Unknown Source:69)
        at io.sentry.core.transport.AsyncConnection$EventSender.run(Unknown Source:6)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
@marandaneto
Copy link
Contributor

hey @PaulWoitaschek thanks for raising this, we'll have a look at it

@PaulWoitaschek
Copy link
Author

@marandaneto If I were you I'd either go with moshi with the code gen or use kotlin serialization.
Then you'll have generated code that doesn't rely on reflection magic like shown in the stack trace.

@marandaneto
Copy link
Contributor

@PaulWoitaschek which device/API have you used? I can't reproduce it on 2 of my devices.

We can't use Kotlin features, this SDK will be the base of the new sentry-java where Kotlin is not that popular yet.
CodeGen also has its downsides, it's always a trade-off.

@marandaneto marandaneto added the question Further information is requested label Jul 2, 2020
@triage-new-issues triage-new-issues bot removed the triage label Jul 2, 2020
@PaulWoitaschek
Copy link
Author

Are you sure you did ran it in release mode?

This is the device:



Name: pixel29

CPU/ABI: Google Play Intel Atom (x86_64)

Path: /home/paul/.android/avd/pixel29.avd

Target: google_apis_playstore [Google Play] (API level 29)

Skin: 1080x1920

SD Card: 512 MB

fastboot.chosenSnapshotFile: 

runtime.network.speed: full

hw.accelerometer: yes

hw.device.name: pixel

hw.lcd.width: 1080

hw.initialOrientation: Portrait

image.androidVersion.api: 29

tag.id: google_apis_playstore

hw.mainKeys: no

hw.camera.front: none

avd.ini.displayname: pixel29

hw.gpu.mode: off

hw.ramSize: 1536

PlayStore.enabled: true

fastboot.forceColdBoot: no

hw.keyboard: yes

hw.sensors.proximity: yes

hw.dPad: no

hw.lcd.height: 1920

vm.heapSize: 16

skin.dynamic: yes

hw.device.manufacturer: Google

hw.gps: yes

skin.path.backup: _no_skin

hw.audioInput: yes

image.sysdir.1: system-images/android-29/google_apis_playstore/x86_64/

showDeviceFrame: no

hw.camera.back: none

AvdId: pixel29

hw.lcd.density: 420

hw.arc: false

hw.device.hash2: MD5:55acbc835978f326788ed66a5cd4c9a7

fastboot.forceChosenSnapshotBoot: no

fastboot.forceFastBoot: yes

hw.trackBall: no

hw.battery: yes

hw.sdCard: yes

tag.display: Google Play

runtime.network.latency: none

disk.dataPartition.size: 6G

hw.sensors.orientation: yes

avd.ini.encoding: UTF-8

hw.gpu.enabled: no

@marandaneto
Copy link
Contributor

thanks, yes, I'll try after lunch again, the only difference was
isDebuggable = true so I could debug it :)

@marandaneto
Copy link
Contributor

marandaneto commented Jul 2, 2020

ok I could reproduce it, it looks like a Gson bug:

https://github.com/google/gson/blob/9d44cbc19a73b45971c4ecb33c8d34d673afa210/gson/src/main/java/com/google/gson/internal/%24Gson%24Types.java#L248

rawType.getGenericInterfaces() returns an empty array but [i] try to access the pos 0.
Trying to find the cause and if there's any work around it.

@marandaneto marandaneto added bug Something isn't working and removed question Further information is requested labels Jul 2, 2020
@marandaneto
Copy link
Contributor

marandaneto commented Jul 3, 2020

some development in the investigation, but I still don't have a fix.

I'm wondering if it's something related to this:

https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

NOTE: appcompat.sh is still under development. It can report
API uses that do not execute at runtime, and reflection uses
that do not exist. It can also miss on reflection uses.
1: Linking greylist,core-platform-api Lsun/misc/Unsafe;->arrayBaseOffset(Ljava/lang/Class;)I use(s):
Lj$/util/concurrent/ConcurrentHashMap;->()V

2: Linking greylist,core-platform-api Lsun/misc/Unsafe;->arrayIndexScale(Ljava/lang/Class;)I use(s):
Lj$/util/concurrent/ConcurrentHashMap;->()V

3: Linking greylist Lsun/misc/Unsafe;->compareAndSwapInt(Ljava/lang/Object;JII)Z use(s):
Lj$/util/concurrent/ConcurrentHashMap;->addCount(JI)V (2 occurrences)
Lj$/util/concurrent/ConcurrentHashMap;->fullAddCount(JZ)V (3 occurrences)
Lj$/util/concurrent/ConcurrentHashMap;->helpTransfer([Lj$/util/concurrent/m;Lj$/util/concurrent/m;)[Lj$/util/concurrent/m;
Lj$/util/concurrent/ConcurrentHashMap;->initTable()[Lj$/util/concurrent/m;
Lj$/util/concurrent/ConcurrentHashMap;->transfer([Lj$/util/concurrent/m;[Lj$/util/concurrent/m;)V (2 occurrences)
Lj$/util/concurrent/ConcurrentHashMap;->tryPresize(I)V (3 occurrences)
Lj$/util/concurrent/r;->a(ILjava/lang/Object;)Lj$/util/concurrent/m;
Lj$/util/concurrent/r;->d()V (2 occurrences)
Lj$/util/concurrent/r;->e()V
Lj$/util/concurrent/x;->a(Lsun/misc/Unsafe;Ljava/lang/Object;JI)I

4: Linking greylist Lsun/misc/Unsafe;->compareAndSwapLong(Ljava/lang/Object;JJJ)Z use(s):
Lj$/util/concurrent/ConcurrentHashMap;->addCount(JI)V (2 occurrences)
Lj$/util/concurrent/ConcurrentHashMap;->fullAddCount(JZ)V (2 occurrences)

5: Linking greylist Lsun/misc/Unsafe;->compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z use(s):
Lj$/util/concurrent/ConcurrentHashMap;->casTabAt([Lj$/util/concurrent/m;ILj$/util/concurrent/m;Lj$/util/concurrent/m;)Z

6: Linking greylist Lsun/misc/Unsafe;->getIntVolatile(Ljava/lang/Object;J)I use(s):
Lj$/util/concurrent/x;->a(Lsun/misc/Unsafe;Ljava/lang/Object;JI)I

7: Linking greylist Lsun/misc/Unsafe;->getObjectVolatile(Ljava/lang/Object;J)Ljava/lang/Object; use(s):
Lj$/util/concurrent/ConcurrentHashMap;->tabAt([Lj$/util/concurrent/m;I)Lj$/util/concurrent/m;

8: Linking greylist,core-platform-api Lsun/misc/Unsafe;->objectFieldOffset(Ljava/lang/reflect/Field;)J use(s):
Lj$/util/concurrent/ConcurrentHashMap;->()V (5 occurrences)
Lj$/util/concurrent/r;->()V

9: Linking greylist Lsun/misc/Unsafe;->putObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;)V use(s):
Lj$/util/concurrent/ConcurrentHashMap;->setTabAt([Lj$/util/concurrent/m;ILj$/util/concurrent/m;)V

10: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
La/e/d/b;->b()Ljava/lang/reflect/Field;

11: Reflection greylist Landroid/app/Activity;->mToken use(s):
La/e/d/b;->f()Ljava/lang/reflect/Field;

12: Reflection greylist Landroid/app/Dialog;->mOnKeyListener use(s):
La/e/k/d;->f(Landroid/app/Dialog;)Landroid/content/DialogInterface$OnKeyListener;

13: Reflection greylist Landroid/content/res/Resources;->mResourcesImpl use(s):
La/b/k/h;->d(Landroid/content/res/Resources;)V

14: Reflection greylist Landroid/graphics/Typeface;->createFromFamiliesWithDefault use(s):
La/e/f/d;->j()V
La/e/f/e;->()V
La/e/f/f;->t(Ljava/lang/Class;)Ljava/lang/reflect/Method;
La/e/f/g;->t(Ljava/lang/Class;)Ljava/lang/reflect/Method;

15: Reflection greylist Landroid/view/View;->computeFitSystemWindows use(s):
La/b/p/d1;->()V

16: Reflection greylist Landroid/view/View;->mAccessibilityDelegate use(s):
La/e/k/n;->e(Landroid/view/View;)Landroid/view/View$AccessibilityDelegate;

17: Reflection greylist-max-p Landroid/view/inputmethod/InputMethodManager;->mH use(s):
Landroidx/activity/ImmLeaksCleaner;->b()V

18: Reflection greylist Landroid/widget/AbsListView;->mIsChildViewEnabled use(s):
La/b/p/f0;->(Landroid/content/Context;Z)V

19: Reflection greylist-max-p Landroid/widget/AutoCompleteTextView;->doAfterTextChanged use(s):
Landroidx/appcompat/widget/SearchView$k;->()V

20: Reflection greylist-max-p Landroid/widget/AutoCompleteTextView;->doBeforeTextChanged use(s):
Landroidx/appcompat/widget/SearchView$k;->()V

21: Reflection greylist-max-p Landroid/widget/AutoCompleteTextView;->ensureImeVisible use(s):
Landroidx/appcompat/widget/SearchView$k;->()V

22: Reflection greylist Landroid/widget/TextView;->getLayoutAlignment use(s):
La/b/p/a0;->z(ILandroid/graphics/RectF;)Z
La/b/p/a0;->z(ILandroid/graphics/RectF;)Z
La/b/p/a0;->z(ILandroid/graphics/RectF;)Z

23: Reflection greylist Landroid/widget/TextView;->nullLayouts use(s):
La/b/p/a0;->u(F)V

24: Reflection greylist-max-o Lcom/android/internal/view/menu/MenuBuilder;->removeItemAt use(s):
La/e/l/i$a;->f(Landroid/view/Menu;)V

25: Reflection greylist Ljava/lang/reflect/AccessibleObject;->override use(s):
Lcom/google/gson/internal/reflect/UnsafeReflectionAccessor;->getOverrideField()Ljava/lang/reflect/Field;

26: Reflection greylist-max-o Ljava/util/DoubleSummaryStatistics;->count use(s):
Lj$/util/r;->()V

27: Reflection greylist-max-o Ljava/util/DoubleSummaryStatistics;->max use(s):
Lj$/util/r;->()V

28: Reflection greylist-max-o Ljava/util/DoubleSummaryStatistics;->min use(s):
Lj$/util/r;->()V

29: Reflection greylist-max-o Ljava/util/DoubleSummaryStatistics;->sum use(s):
Lj$/util/r;->()V

30: Reflection greylist-max-o Ljava/util/IntSummaryStatistics;->count use(s):
Lj$/util/t;->()V

31: Reflection greylist-max-o Ljava/util/IntSummaryStatistics;->max use(s):
Lj$/util/t;->()V

32: Reflection greylist-max-o Ljava/util/IntSummaryStatistics;->min use(s):
Lj$/util/t;->()V

33: Reflection greylist-max-o Ljava/util/IntSummaryStatistics;->sum use(s):
Lj$/util/t;->()V

34: Reflection greylist-max-o Ljava/util/LongSummaryStatistics;->count use(s):
Lj$/util/y;->()V

35: Reflection greylist-max-o Ljava/util/LongSummaryStatistics;->max use(s):
Lj$/util/y;->()V

36: Reflection greylist-max-o Ljava/util/LongSummaryStatistics;->min use(s):
Lj$/util/y;->()V

37: Reflection greylist-max-o Ljava/util/LongSummaryStatistics;->sum use(s):
Lj$/util/y;->()V

38: Reflection greylist Lsun/misc/Unsafe;->allocateInstance use(s):
Lcom/google/gson/internal/UnsafeAllocator;->create()Lcom/google/gson/internal/UnsafeAllocator;

39: Reflection greylist Lsun/misc/Unsafe;->theUnsafe use(s):
Lj$/util/concurrent/x;->b()Ljava/lang/reflect/Field;
Lcom/google/gson/internal/UnsafeAllocator;->create()Lcom/google/gson/internal/UnsafeAllocator;
Lcom/google/gson/internal/reflect/UnsafeReflectionAccessor;->getUnsafeInstance()Ljava/lang/Object;

39 hidden API(s) used: 9 linked against, 30 through reflection
22 in greylist
0 in blacklist
13 in greylist-max-o
4 in greylist-max-p
0 in greylist-max-q
To run an analysis that can give more reflection accesses,
but could include false positives, pass the --imprecise flag.

@marandaneto
Copy link
Contributor

marandaneto commented Jul 3, 2020

so I found out the issue, but I'm gonna raise an issue to the R8 team as well, I'll release a fix for now.

https://github.com/getsentry/sentry-android/blob/master/sentry-core/src/main/java/io/sentry/core/protocol/Contexts.java#L5

class Contexts extends ConcurrentHashMap<String, Object>
when a class extends ConcurrentHashMap and it's used on reflection, something goes wrong and I really don't see how to fix that, I've tried adding many stuff to the proguard rules file, but it didn't work.

I'll extend HashMap for now, as we don't really need this class to be thread-safe, but when we'd be moving this class to the Scope, we'd need to find a different solution.

@marandaneto
Copy link
Contributor

@PaulWoitaschek I've got a fix for this, #478 and this would avoid reflection for this class and its children, I'll do a bit more of testing and if all good, you can expect a new version on Monday morning :)

@ZueFe
Copy link

ZueFe commented Jul 6, 2020

@marandaneto thanks for all the work, was just curious is there any ETA on when this pull request might appear in new release? thanks

@marandaneto
Copy link
Contributor

released: https://github.com/getsentry/sentry-android/releases/tag/2.2.1

let us know if you find any issues, thanks for reporting this.

@PaulWoitaschek
Copy link
Author

Thanks for tackling this so quickly!

@marandaneto
Copy link
Contributor

marandaneto commented Jul 10, 2020

JFI: I've raised an issue on R8 team https://issuetracker.google.com/issues/160909126

@PaulWoitaschek
Copy link
Author

Btw, checking back on this; our events are now arriving!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants