Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix DSO name hash generation on Windows #9315

Merged
merged 1 commit into from
Sep 23, 2024

Conversation

grendello
Copy link
Contributor

Fixes: #9200

@jonpryor found that on Windows, shared library name hashes are
generated using the Windows path separator character, while the
runtime expects a Unix one. This discrepancy leads to different
hashes for the same satellite assembly on Linux/macOS and Windows.

Fix by explicitly converting any \ characters in the satellite
assembly name to / prior to hash generation.

Fixes: #9200

@jonpryor found that on Windows, shared library name hashes are
generated using the Windows path separator character, while the
runtime expects a Unix one.  This discrepancy leads to different
hashes for the same satellite assembly on Linux/macOS and Windows.

Fix by explicitly converting any `\` characters in the satellite
assembly name to `/` prior to hash generation.
@jonpryor
Copy link
Member

jonpryor commented Sep 23, 2024

[Xamarin.Android.Build.Tasks] Fix DSO name hash generation on Windows

Fixes: https://github.com/dotnet/android/issues/9200

Context: 86260ed36dfe1a90c8ed6a2bb1cd0607d637f403

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   :       #01 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   :       #02 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   :       #03 pc 0000000000209de0  /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db)
	F DEBUG   :       #04 pc 00000000002072cc  /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (mono_assembly_request_byname+972) (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db)
	F DEBUG   :       #05 pc 0000000000204de4  /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db)
	F DEBUG   :       #06 pc 0000000000236c8c  /data/app/~~UeL3IzhnnKWaWNC3QvJzLQ==/com.companyname.testnet9-JRe5kbYFfMvbdm6sggxl4Q==/lib/arm64/libmonosgen-2.0.so (BuildId: ed96d22c7f8696c1b93010ad15c389fcae5460db)
	F DEBUG   :       #07 pc 0000000000007ee4  <anonymous:7b0493d000>

In 86260ed3 (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 86260ed3.

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

@jonpryor jonpryor merged commit 852c38e into main Sep 23, 2024
58 checks passed
@jonpryor jonpryor deleted the dev/grendel/satellite-names-on-windows-fix branch September 23, 2024 18:48
@github-actions github-actions bot locked and limited conversation to collaborators Oct 24, 2024
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[.net9-preview][android] Multiple AppResources Crash - failed to load bundled assembly pt-PT/
4 participants