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

App Crashes when using bundle.config with abi splits set to negate. #8979

Closed
dellis1972 opened this issue May 23, 2024 · 5 comments · Fixed by #8987
Closed

App Crashes when using bundle.config with abi splits set to negate. #8979

dellis1972 opened this issue May 23, 2024 · 5 comments · Fixed by #8987
Assignees
Labels
Area: App Runtime Issues in `libmonodroid.so`.

Comments

@dellis1972
Copy link
Contributor

Android application type

.NET Android (net7.0-android, net8.0-android, etc.)

Affected platform version

.net8.0-android, .net9.0-android

Description

When using a bundle.config with the following contents

{
	"compression": { },
	"optimizations": {
		"splitsConfig": {
			"splitDimension": [
				{
						"value": "ABI",
						"negate": true
				}
			 ],
		}
	}
}

the app crashes at runtime with the following error.

At least a single application lib directory must be added"

Steps to Reproduce

  1. Download the attached repo app.
  2. Build and run it using the latest main of .net android.

Did you find any workaround?

Changing "negate": true to "negate": false fixes the issue.

Relevant log output

No response

@dellis1972 dellis1972 added Area: App Runtime Issues in `libmonodroid.so`. needs-triage Issues that need to be assigned. labels May 23, 2024
@dellis1972
Copy link
Contributor Author

MyApp.zip

@dellis1972 dellis1972 removed the needs-triage Issues that need to be assigned. label May 23, 2024
@dellis1972
Copy link
Contributor Author

logcat-failed.log.zip

@dellis1972
Copy link
Contributor Author

So I think I know what is causing the issue

This is the contents of the apks file which google will generate for a specific device.

This is with negate set to false

 extracting: foo/toc.pb              
 extracting: foo/asset-slices/assetpack1-astc.apk  
 extracting: foo/asset-slices/assetpack1-dxt1.apk  
 extracting: foo/asset-slices/assetpack1-etc1_rgb8.apk  
 extracting: foo/asset-slices/assetpack1-master.apk  
 extracting: foo/asset-slices/assetpack1-paletted.apk  
 extracting: foo/splits/base-arm64_v8a.apk  
 extracting: foo/splits/base-arm64_v8a_2.apk  
 extracting: foo/splits/base-armeabi_v7a.apk  
 extracting: foo/splits/base-armeabi_v7a_2.apk  
 extracting: foo/splits/base-master.apk  
 extracting: foo/splits/base-master_2.apk  
 extracting: foo/splits/base-master_3.apk  
 extracting: foo/splits/base-x86.apk  
 extracting: foo/splits/base-x86_2.apk  
 extracting: foo/splits/base-x86_64.apk  
 extracting: foo/splits/base-x86_64_2.apk

This is with it set to true

 extracting: foo/toc.pb              
 extracting: foo/asset-slices/assetpack1-astc.apk  
 extracting: foo/asset-slices/assetpack1-dxt1.apk  
 extracting: foo/asset-slices/assetpack1-etc1_rgb8.apk  
 extracting: foo/asset-slices/assetpack1-master.apk  
 extracting: foo/asset-slices/assetpack1-paletted.apk  
 extracting: foo/splits/base-master.apk  
 extracting: foo/splits/base-master_2.apk  
 extracting: foo/splits/base-master_3.apk

If we look at the contents of "base-master.apk" in the latter, we see that it contains ALL .so files for all abis not just the resources. On the former , those .so files are split into a seperate base-XXX.apk .

@dellis1972
Copy link
Contributor Author

So I tried this patch https://gist.github.com/dellis1972/2a3f62c4b7728dd33c621d823640fba7

This adds an additional fallback to

if (Util::ends_with (apk, SharedConstants::split_config_abi_apk_name)) {
if (Util::ends_with (apk, SharedConstants::split_config_abi_apk_name) || Util::ends_with (apk, SharedConstants::base_apk_name)) {

Now I get an error

Abort message: '/Users/dean/Documents/Sandbox/Xamarin/xamarin-android/src/native/monodroid/embedded-assemblies.hh:180 (ensure_valid_assembly_stores): Invalid or incomplete assembly store data

So something about the assembly stores gets messed up by this.

@grendello
Copy link
Contributor

The problem is here https://github.com/xamarin/xamarin-android/blob/main/src/native/runtime-base/android-system.cc#L740-L747

Previously, whenever split configs were present, the shared libraries always lived in a file named split_config.ARCH.apk (with ARCH replaced by e.g. arm64) and so, for performance reasons, we skip scanning anything that's not a file named like that if we detect that split_config.* files exist.

In this case the split files do exist, but shared libraries are all in base.apk and the architecture-specific split config doesn't exist at all:

$ adb shell run-as com.xamarin.runapplicationwithassetpacktextureformats ls -l /data/app/~~SiaOe7UQLju6w_cxUf4LsA==/com.xamarin.runapplicationwithassetpacktextureformats-Z7cymJN9yrWULwTPJncm_Q==/
total 28479
-rw-r--r-- 1 system system 29080982 2024-05-24 18:07 base.apk
drwxr-xr-x 3 system system     3452 2024-05-24 18:07 lib
-rw-r--r-- 1 system system     8478 2024-05-24 18:07 split_assetpack1.apk
-rw-r--r-- 1 system system     8559 2024-05-24 18:07 split_assetpack1.config.astc.apk
-rw-r--r-- 1 system system    16808 2024-05-24 18:07 split_config.xxxhdpi.apk

I need to think about it a bit, so that we don't hurt startup performance with the fix.

dellis1972 pushed a commit that referenced this issue Jun 17, 2024
…e.apk (#8987)

Fixes: #8979

When bundle configuration uses standard settings for split configs, the per-ABI library
directory (which contains all of our DSOs/assemblies/blobs etc) will be placed in a per-ABI
split config file named split_config.{ARCH}.apk and we use the fact to optimize startup
time.

However, if a custom build config file with the following settings is found, Android bundletool
doesn't create the per-ABI split config file, and so we need to search all the files in order
to find shared libraries, assemblies/blobs etc:

```
{
  "optimizations": {
    "splitsConfig": {
      "splitDimension": [
        {
          "value": "ABI",
          "negate": true
        }
      ],
    }
  }
}
```

The presence or absence of split config files is checked in our Java startup code which will
notice that split configs are present, but will not check (for performance reasons, to avoid
string comparisons) whether the per-ABI split config is present. We, therefore, need to let
our native runtime know in some inexpensive way that the split configs should be ignored and
that the DSOs/assemblies/blobs should be searched for in the usual, non-split config, way.

Since we know at build time whether this is the case, it's best to record the fact then and
let the native runtime merely check a boolean flag instead of dynamic detection at each app
startup.
@github-actions github-actions bot locked and limited conversation to collaborators Jul 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App Runtime Issues in `libmonodroid.so`.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants