1

I have in beta tests that is getting ANRs on a Pixel, and a Pixel 2 XL both running 8.1. From the logs I am getting back it appears that the call to AAssetManager_open is blocked waiting for a mutex to unlock.

From the log there is not discernible threading conflicts. On the one device it is happen on the third asset read as the app is loading. All of which are separate (and clean up) but sequential. The other device the deadlock is later. No threads are touching related code.

I have yet to encounter this issue on another device so I can't even play with it locally to understand further (I don't have either device). From what Android source I could find the mutex locked doesn't have anything complex about its usage.

The calls are happening on the main thread (hence the ANRs), so I can patch the issue by moving them off there. Ideally, though, I want to fix (or at least understand the cause of) the underlying problem of why the deadlock is happening on these devices in the first place.

So, what I am wondering is if there are any known ways to create a deadlock with AAssetManager_open?

On a side note, the closet I have found is a single article that mentions in passing people getting ANRs on AAssetManager_open in the Oreo pre-release builds but I can't find anything else on that.

Edit: I know have a crash on a different 8.1 device (OnePlus5), so it appears to not be specific to Pixel but 8.1 in general.

I also moved what AssetManager reads were on the main thread just incase and as expected the issue still exists (just don't get an ANR).

Edit #2: It is specific to 8.1 with AdMob mediation.

ajso
  • 73
  • 7

2 Answers2

0

Opening an asset may be a blocking operation. Some assets are stored uncompressed, and AAssetManager_open() can return handle to work with the 'file' in-place. Other assets must be uncompressed to a local cache before they can be used. Some of these files will already be unzipped to your disk, and AAssetManager_open() will return almost instantaneously. Others must be unzipped, and this will compete for CPU with other threads, producing ANR if you are unlucky.

The bottom line, do your best to open assets not from the UI thread.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • It is a blocking operation (hence, deadlock). It is not zipped vs unzipped in the apk though since it happens with both types of APK storage. Also, as I said, one is happening really early. Unless some other activity can load assets from my APK, I am unclear who holds the lock. I am very suspicious of it being a matter of luck since it is consistent on Pixel 8.1 devices, and has yet to appear on either other 8.1 or non Pixel devices. – ajso May 09 '18 at 21:15
  • How do you know it's a *deadlock*? ANR does not need long delay to fire. Possibly, Pixel has lower ANR threshold than other devices. – Alex Cohn May 09 '18 at 21:58
  • Because it is waiting on a mutex: #01 pc 000000000004802d /system/lib/libc.so (__pthread_mutex_lock_with_timeout(pthread_mutex_internal_t*, bool, timespec const*)+164) – ajso May 09 '18 at 22:15
  • The ANR threshold is an interesting thought though., I don't suppose you know of any resources with what it may be ? I know the docs still claim 5 seconds, and I assume Google wouldn't violate their own guidelines on their own devices though. – ajso May 09 '18 at 22:35
0

The reason of deadlock can be invalid pointer to AAssetManager. Please make sure, that pointer which you get from AAssetManager_fromJava is still valid (was not destroyed by GC).

link to AAssetManager_fromJava description

kpdev
  • 610
  • 1
  • 7
  • 20
  • That was it. Apparently 8.1 + ads leads to it getting cleaned up & replaced. Previous stuff build on the code base apparently never hit a situation where it was deleted. Thank-you very much! – ajso Jun 10 '18 at 00:11