Commit f90e889
[native] Fix JNI preload cache generation (#10547)
Fixes: #10544
Context: 1a62af3
Context: cba39dc
cba39dc introduced code to preload at startup native libraries which use JNI,
to work around an issue in Android which prevents such libraries from being
properly loaded at the later time of application life.
Part of the workaround was support for updating handle of such a library in
our shared library cache. Since every library has different entries in the
cache (because we search the array using xxHash generated from various forms
of the library name), after preloading it we had to update every entry in the
DSO cache with the correct handle, so that the library is never loaded again.
The code which generates the caches and indexes at application build time worked
fine in my testing (using `dotnet build`) but it turns out that using `dotnet publish`
instead breaks the code in a subtle, but nasty way.
The issue is that the code which generated the index of shared libraries to preload
reused an array which stored the indexes, while generating code for different RIDs.
This resulted in the very first RID to process to contain valid indexes, the
second one would **append** its own indexes to the preceding RID's data, the third
RID would further append its own data etc.
This would result in the following index code generated for the subsequend RIDs:
```
; android-arm
; Indices into dso_cache[] of DSO libraries to preload because of JNI use
@dso_jni_preloads_idx = dso_local local_unnamed_addr constant [4 x i32] [
i32 15, ; libSystem.Security.Cryptography.Native.Android.so
i32 0, ; libSystem.Security.Cryptography.Native.Android
i32 7, ; System.Security.Cryptography.Native.Android.so
i32 8 ; System.Security.Cryptography.Native.Android
], align 4
```
```
; android-arm64
; Indices into dso_cache[] of DSO libraries to preload because of JNI use
@dso_jni_preloads_idx = dso_local local_unnamed_addr constant [8 x i32] [
i32 15, ; libSystem.Security.Cryptography.Native.Android.so
i32 0, ; libSystem.Security.Cryptography.Native.Android
i32 7, ; System.Security.Cryptography.Native.Android.so
i32 8, ; System.Security.Cryptography.Native.Android
i32 10, ; Invalid index 4
i32 0, ; Invalid index 5
i32 1, ; Invalid index 6
i32 14 ; Invalid index 7
], align 4
```
```
; android-x64
; Indices into dso_cache[] of DSO libraries to preload because of JNI use
@dso_jni_preloads_idx = dso_local local_unnamed_addr constant [12 x i32] [
i32 15, ; libSystem.Security.Cryptography.Native.Android.so
i32 0, ; libSystem.Security.Cryptography.Native.Android
i32 7, ; System.Security.Cryptography.Native.Android.so
i32 8, ; System.Security.Cryptography.Native.Android
i32 10, ; Invalid index 4
i32 0, ; Invalid index 5
i32 1, ; Invalid index 6
i32 14, ; Invalid index 7
i32 10, ; Invalid index 8
i32 0, ; Invalid index 9
i32 1, ; Invalid index 10
i32 14 ; Invalid index 11
], align 16
```
In effect, when running on an arm64 device, we would try to load, and cache the
handle, of an entirely different shared library, leading to further problems to
find a requested symbol:
```
10-17 11:25:18.062 27900 27900 F monodroid-assembly: Failed to load symbol 'AndroidCryptoNative_EcKeyCreateByKeyParameters' from shared library 'libSystem.Security.Cryptography.Native.Android'
10-17 11:25:18.110 1444 4298 I ActivityManager: Process com.companyname.test_jwt (pid 27900) has died: fg TOP
10-17 11:25:18.110 1444 1712 I libprocessgroup: Removed cgroup /sys/fs/cgroup/apps/uid_10361/pid_27900
10-17 11:25:18.111 913 913 I Zygote : Process 27900 exited cleanly (0)
```
Native code attempted to load the symbol from a library that happened to be
stored at the index valid for `android-arm` but not for e.g. `android-arm64`,
which was not `libSystem.Security.Cryptography.Native.Android`, leading to
the above red herring error.
Note: if **all** of RIDs enabled for the application are 32-bit or **all**
of them are 64-bit, things would work even though the generated code would
be technically incorrect. This is because all of the hashes and, thus, sort
order of the `dso_cache` entries would be the same.
Fix this by making sure that the index array is not shared between different
RIDs when generating the DSO cache code.1 parent 4860105 commit f90e889
File tree
4 files changed
+8
-14
lines changed- src
- Xamarin.Android.Build.Tasks/Utilities
- native
- clr/include/host
- mono/pinvoke-override
4 files changed
+8
-14
lines changedLines changed: 3 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
282 | | - | |
| 282 | + | |
283 | 283 | | |
284 | 284 | | |
285 | 285 | | |
| |||
369 | 369 | | |
370 | 370 | | |
371 | 371 | | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
376 | | - | |
377 | 372 | | |
378 | 373 | | |
379 | 374 | | |
| |||
382 | 377 | | |
383 | 378 | | |
384 | 379 | | |
| 380 | + | |
| 381 | + | |
385 | 382 | | |
386 | 383 | | |
387 | 384 | | |
| |||
Lines changed: 3 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
383 | 383 | | |
384 | 384 | | |
385 | 385 | | |
386 | | - | |
| 386 | + | |
387 | 387 | | |
388 | 388 | | |
389 | 389 | | |
| |||
601 | 601 | | |
602 | 602 | | |
603 | 603 | | |
604 | | - | |
605 | | - | |
606 | | - | |
607 | | - | |
608 | | - | |
609 | 604 | | |
610 | 605 | | |
611 | 606 | | |
| |||
614 | 609 | | |
615 | 610 | | |
616 | 611 | | |
| 612 | + | |
| 613 | + | |
617 | 614 | | |
618 | 615 | | |
619 | 616 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
0 commit comments