Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Fix DSO name hash generation on Windows (
Browse files Browse the repository at this point in the history
…#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
grendello authored Sep 23, 2024
1 parent b667af5 commit 852c38e
Showing 1 changed file with 1 addition and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ void AddAssemblyImageCache (LlvmIrModule module, out AssemblyCacheState acs)
foreach (string name in uniqueAssemblyNames) {
// We must make sure we keep the possible culture prefix, which will be treated as "directory" path here
string cultureName = Path.GetDirectoryName (name) ?? String.Empty;
string clippedName = Path.Combine (cultureName, Path.GetFileNameWithoutExtension (name));
string clippedName = Path.Combine (cultureName, Path.GetFileNameWithoutExtension (name)).Replace (@"\", "/");
string inArchiveName;

if (cultureName.Length == 0) {
Expand Down

0 comments on commit 852c38e

Please sign in to comment.