Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] Fix DSO name hash generation on Windows (…
…#9315) Fixes: #9200 Context: 86260ed If you use .NET resource files for localization, a'la: 1. Create new .net MAUI project `dotnet new maui` 2. Add `AppResources.resx` 3. Add `AppResources.pt.resx` 4. Add [Translation to a Page][0] 5. Build the app in Release configuration: `dotnet build -c Release` 6. Run the app from (5) If (5) is done *on macOS or Linux*, then (6) will run fine. If (5) is done *on Windows*, then (6) will crash: W monodroid-assembly: Assembly 'pt-PT/Testnet9.resources' (hash 0x1cab5580a98905b0) not found W monodroid-assembly: open_from_bundles: failed to load bundled assembly pt-PT/Testnet9.resources W monodroid-assembly: Assembly 'pt-PT/Testnet9.resources' (hash 0x1cab5580a98905b0) not found W monodroid-assembly: open_from_bundles: failed to load bundled assembly pt-PT/Testnet9.resources F monodroid-assembly: Failed to look up image index for hash 0x7357acbda27bdba3 F monodroid: Abort at /Users/runner/work/1/s/xamarin-android/src/native/monodroid/mono-image-loader.hh:120:5 ('static MonoImage *xamarin::android::internal::MonoImageLoader::stash_and_return(MonoImage *, MonoImageOpenStatus, hash_t)') F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 8622 (nyname.testnet9), pid 8622 (nyname.testnet9) … I crash_dump64: performing dump of process 8622 (target tid = 8622) F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** F DEBUG : Build fingerprint: 'google/raven/raven:14/AP2A.240805.005.F1/12043167:user/release-keys' F DEBUG : Revision: 'MP1.0' F DEBUG : ABI: 'arm64' F DEBUG : Timestamp: 2024-09-19 14:56:09.282050201-0400 F DEBUG : Process uptime: 1s F DEBUG : Cmdline: com.companyname.testnet9 F DEBUG : pid: 8622, tid: 8622, name: nyname.testnet9 >>> com.companyname.testnet9 <<< F DEBUG : uid: 10432 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- F DEBUG : Abort message: 'Failed to look up image index for hash 0x7357acbda27bdba3' F DEBUG : x0 0000000000000000 x1 00000000000021ae x2 0000000000000006 x3 0000007fe644e310 F DEBUG : x4 2e722e302e6a716e x5 2e722e302e6a716e x6 2e722e302e6a716e x7 7f7f7f7f7f7f7f7f F DEBUG : x8 00000000000000f0 x9 0000007af562a350 x10 0000000000000001 x11 0000007af567b170 F DEBUG : x12 0000007fe644cc20 x13 00000000000000de x14 0000007fe644de48 x15 0000003e2efa613a F DEBUG : x16 0000007af56e1fd0 x17 0000007af56cd560 x18 0000007b1573c000 x19 00000000000021ae F DEBUG : x20 00000000000021ae x21 00000000ffffffff x22 000000773e5ed5a8 x23 000000784cd6dc8c F DEBUG : x24 000000773e5ed5c0 x25 0000007b14e0aac0 x26 0000007fe644e428 x27 0000007b14e0aac0 F DEBUG : x28 0000000000000001 x29 0000007fe644e390 F DEBUG : lr 0000007af56648b8 sp 0000007fe644e2f0 pc 0000007af56648e4 pst 0000000000001000 F DEBUG : 8 total frames F DEBUG : backtrace: F DEBUG : #00 pc 000000000005d8e4 /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 1d36f8ae6e0af6158793abea7d4f4f2b) F DEBUG : #1 pc 00000000000450bc /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonodroid.so (xamarin::android::Helpers::abort_application(bool, std::__ndk1::source_location)+68) (BuildId: 2c6d565f407362f1538c0daa0faadd527d3f394d) F DEBUG : #2 pc 000000000001ffe4 /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::open_from_bundles(void*, _MonoAssemblyName*, char**, void*, _MonoError*)+5672) (BuildId: 2c6d565f407362f1538c0daa0faadd527d3f394d) F DEBUG : #3 pc 0000000000209de0 /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db) F DEBUG : #4 pc 00000000002072cc /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (mono_assembly_request_byname+972) (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db) F DEBUG : #5 pc 0000000000204de4 /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db) F DEBUG : #6 pc 0000000000236c8c /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db) F DEBUG : #7 pc 0000000000007ee4 <anonymous:7b0493d000> In 86260ed (and earlier?), assemblies are not loaded "by name". Instead, at build-time assembly names are *hashed*, and at runtime the name of the assembly to load is also hashed, and we load the assembly based on the assembly name hash; see e.g. `AssemblyStoreIndexEntry::name_hash` from 86260ed. Additionally, with resource assemblies we don't hash *just* the assembly name, e.g. `Testnet9.resources.dll`, but also include the "directory" containing the assembly, e.g. `pt/Testnet9.resources.dll`. Of note is the directory separator character to use: the value hashed at runtime is in `EmbeddedAssemblies::open_from_bundles()`: if (culture != nullptr && *culture != '\0') { name.append_c (culture); name.append (zip_path_separator); } name.append_c (asmname); `zip_path_separator` is `/`, meaning that the compile-time hash values *also* need to use `/` to be consistent. The problem is that `/` *wasn't* consistently used to build the compile-time hash values; `MarshalMethodsNativeAssemblyGenerator.AddAssemblyImageCache()` used `Path.Combine()`, which would use `\` on Windows, not `/`. The result is that if the app was built on Windows, the compile-time data would hash e.g. `pt\Testnet9.dll`, which would be a different hash value than that produced by `pt/Testnet9.dll`. This in turn would result in a "lookup miss": F monodroid-assembly: Failed to look up image index for hash 0x7357acbda27bdba3 followed by an abort. Fix this by updating `AddAssemblyImageCache()` to normalize on `/`. [0]: https://learn.microsoft.com/dotnet/maui/fundamentals/localization?view=net-maui-8.0
- Loading branch information