New issue
Advanced search Search tips

Issue 882871 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Oct 9
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug
Proj-VR
Proj-XR
Proj-XR-VR

Blocking:
issue 874564



Sign in to add a comment

chrome_modern_public_bundle cannot load an .so at runtime

Project Member Reported by cjgrant@chromium.org, Sep 11

Issue description

A portion of VR native code hopes to move into an .so, opened at runtime if necessary, and supplied via the new VR dynamic feature module.  Other VR native code is not moving into the module.  It is the base-library native VR code that will be opening the .so VR code.  That gives a call chain like:

Java -> [Java VR DFM] --(jni)--> Native -> dlopen() -> [Native VR .so from DFM]

Here's how things look in a few bundle/APK variants:


chrome_public_apk:  This works.  The VR module library’s name is libvr_ui.so, and loading the module works fine - I’ve run VR like this before successfully.

chrome_modern_public_apk:  I haven’t tried this until today.  libvr_ui.so doesn’t open, possibly because I’m calling dlopen() to look for libvr_ui.so when the library has been renamed to crazy.libvr_ui.so.  This failure probably isn’t relevant, since there are no plans to make this case work.

chrome_public_bundle:  We can’t directly test this case, because there’s no VR Java code in this bundle.  We could hack it by inserting a dlopen() call 

chrome_modern_public_bundle:  This is the odd case that fails.  The VR .so is found, but dlopen() fails due to “cannot find libchrome.so”.  I notice that libchrome.so is actually crazy.libchrome.so, but I’m not sure if this is relevant.

In a follow-on comment, I’ll post a CL that reproduces the failure on startup, by hacking the build to open the VR library on startup (rather than during the VR device-on flow).

 
Blocking: 874564
A few explanations for what you're seeing:

chrome_public_apk: In this mode, the library is always extracted from the APK at installation time by the package manager (under /data/data/<app-package>/lib/). This is why libvrui.so is visible to the crazy linker (or the system linker).

Technically, we could load the library directly from the APK, but there are some OEM-specific platform bugs that prevent this from working sometimes :-/

chrome_modern_public_apk: In this case, the crazy linker will load libraries directly from the APKs. This is done by using the magic "crazy." prefix when storing the library (this ensures the package manager ignores the file at installation time, i.e. never extracts it). Meanwhile, the crazy linker will automatically look for crazy.libfoo.so if you ask for libfoo.so.

The reason why libvrui.so doesn't load is very probably because the crazy linker needs to know where to look. By default, it is configured to only look in base.apk. You should be able to call org.chromium.base.Linker.addZipArchivePath() to add the path of the VR split APK to the search path, then loading will work. This is annoying, which is why I've filed [1] to do that automatically for you.

The alternative is to use a path like "/path/to/apk!lib/armeabi-v7a/libvrui.so" when calling dlopen() or Linker.loadLibrary(). This is also recognized by the system linker starting with Android M by the way. 

I have no explanation for the chrome_modern_public_bundle issue that you're seeing. libchrome.so should definitely already be in the default search path (and as I've said, the crazy. prefix should be handled transparently by the crazy linker, i.e. you should never need to specify it yourself).

It would be interesting to reproduce the issue while enabling the linker traces:

third_party/android_crazy_linker/src/src/crazy_linker_debug.h: set default value for CRAZY_DEBUG to 1
base/android/linker/linker_jni.cc: Set DEBUG from 0 to 1

This will print extra traces to the logcat.
Since there is nothing really specific to VR in this bug, I'm going to write a test bundle with several native libraries in several modules to see how things go. If you have a prototype CL, I'd be happy to take a look. In all cases, we will need this for some kind of integration tests anyway (to check that everything works in bundles as expected, crazy linker or not).
Here's a test CL that packages all remaining native module work and a hack to just open the VR library on startup (I use AutocompleteController for nostalgic reasons):

https://crrev.com/c/1219846


Target:  chrome_modern_public_bundle

My gn args:

target_os = "android"
use_goma = true
disable_incremental_isolated_processes = true
is_chrome_branded = true
is_debug = false
is_java_debug = true

Note the "is_java_debug" arg - this is working around a proguard problem with native libraries in modules.  I assume it's completely unrelated to the issue at hand.
I'll try CRAZY_DEBUG now.
With debugging on, I don't see CrazyLinker making a peep during dlopen():

chromium: [INFO:autocomplete_controller_android.cc(149)] Trying to open VR module library
chromium: [FATAL:autocomplete_controller_android.cc(151)] Check failed: lib != nullptr. dlopen failed: library "libchrome.so" not found

That doesn't seem good.
Cc: -cjgrant@chromium.org
Owner: cjgrant@chromium.org
This is resolved now.  The issue was caused by some portions of the build depending on libchrome, while most others depend on libchrome_base_module.  Specifically, (at least) the generate_resource_whitelist() rule depends on libchrome, and also explicitly lists libchrome's libraray filename as an input.

The same modifications also make the monochrome bundle work.
Status: Fixed (was: Assigned)

Sign in to add a comment