[native] When preloading shared JNI libraries, update alias entries too#10444
Merged
[native] When preloading shared JNI libraries, update alias entries too#10444
Conversation
Context: ee43633 Hitting F5 in Visual Studio for a `dotnet new maui` app produces a loop such as: 08-25 09:40:36.759 32259 32293 D monodroid-assembly: monodroid_dlopen: hash match found, DSO name is 'libSystem.Security.Cryptography.Native.Android.so' 08-25 09:40:36.759 32259 32293 D monodroid-assembly: Trying to load loading shared JNI library /data/user/0/com.companyname.testgrendel/files/.__override__/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so with System.loadLibrary 08-25 09:40:36.759 32259 32293 D monodroid-assembly: Running DSO loader on thread 32293, dispatching to main thread This does not happen for: * `dotnet new android` project * At the command-line * Using Ctrl+F5 in Visual Studio I was able to also reproduce this issue in a `static MainActivity` constructor that uses `HttpClient`, adding a test doing the same thing.
51af2cc to
e522144
Compare
Contributor
Author
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context: cba39dc
Context: #10376
Context: #10324
cba39dc implemented preloading of JNI-using native libraries but it missed to update
alias entries for each preloaded library.
During application build we generate native code that contains cache for each native
library packaged with the managed application code. Each library follows the same
naming pattern:
lib<NAME>.so. However, the managed code can refer to those libraries(when e.g. declaring a p/invoke with the
[DllImporrt]attribute) using different formsof names. The request may have a form of
lib<NAME>or<NAME>etc.When the runtime tries to resolve the p/invoke symbol, it first needs to load the shared
library. This is done (in our case) by using a callback into our runtime which then tries
to find the library and load it. Should the attempt fail, the runtime will mutate the
library name and ask as again until all the possible names are tried or the library is
loaded successfully. This roundtrip is pretty expensive, so in our native library loader
code we implemented (in c227042) a scheme where at build time we mutate library names
ourselves and a separate entry for each name mutation in the shared library cache. This
way, when the runtime request comes, we perform a single search and are able to find
the library no matter what name the managed code requested.
Each of the cache entries contains, among other things irrelevant to this PR, a field
which stores the native library's handle, after it is loaded. cba39dc loaded the
library and set that field in just a single cache entry, the one corresponding to the
canonical library name (
lib<NAME>.so) but it failed to set the field in all the aliases.This resulted in an attempt to load the library again, with the managed code requesting it
by a different name, finding the corresponding cache entry and seeing that its handle is
unset. However, since the request was sent from a different thread, we attempted to load
the library on the main thread (described in detail in cba39dc commit message), which
attempt always failed leading to an endless loop and application crash/hang while debugging.
Fix the issue by setting native shared library handle in all the cache entries corresponding
to various mutations of the library name. This makes sure that further requests to load the
library will see the handle set in cache and use it, instead of attempting to load the it
again.