dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.14k stars 4.71k forks source link

ICU causes crash on iOS 17.4 simulator #98941

Closed rolfbjarne closed 5 months ago

rolfbjarne commented 7 months ago

Description

App crashes when iOS starts using its own ICU code.

I'm guessing it's because of a symbol clash with Mono's ICU symbols.

Reproduction Steps

  1. Install Xcode 15.3 beta 3.
  2. Create a new iOS project: dotnet new ios
  3. Add this to FinishedLaunching in AppDelegate.cs:
var date = NSDate.Now;
var locale = NSLocale.SystemLocale;
var str = date.DescriptionWithLocale (locale);
  1. Run in an iOS 17.4 simulator

Note: an iOS 17.2 simulator works just fine.

Expected behavior

No crash.

Actual behavior

Crash:

Thread 0 Crashed:: tid_103 Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib                 0x1129293b0 __pthread_kill + 8
1   libsystem_pthread.dylib                0x112557130 pthread_kill + 256
2   libsystem_c.dylib                      0x1801655c0 abort + 104
3   libmonosgen-2.0.dylib                  0x113316bcc sigabrt_signal_handler.cold.1 + 48
4   libmonosgen-2.0.dylib                  0x113043a60 sigabrt_signal_handler + 196
5   libsystem_platform.dylib               0x1123237e0 _sigtramp + 52
6   libsystem_pthread.dylib                0x112557130 pthread_kill + 256
7   libsystem_c.dylib                      0x1801655c0 abort + 104
8   libsystem_malloc.dylib                 0x1801e378c malloc_vreport + 900
9   libsystem_malloc.dylib                 0x1801e3950 malloc_report + 60
10  libsystem_malloc.dylib                 0x1801d78a0 find_zone_and_free + 456
11  libicucore.A.dylib                     0x181dbf2a0 icu::Locale::setToBogus() + 48
12  libicucore.A.dylib                     0x181dc0c44 icu::Locale::operator=(icu::Locale const&) + 36
13  libicucore.A.dylib                     0x181f2e5f4 icu::number::LocalizedNumberFormatter::LocalizedNumberFormatter(icu::number::impl::MacroProps&&, icu::Locale const&) + 212
14  libicucore.A.dylib                     0x181eda738 icu::DecimalFormat::touch(UErrorCode&) + 204
15  libicucore.A.dylib                     0x181edade8 icu::DecimalFormat::DecimalFormat(icu::UnicodeString const&, icu::DecimalFormatSymbols*, UNumberFormatStyle, UErrorCode&) + 328
16  libicucore.A.dylib                     0x181f491b0 icu::NumberFormat::makeInstance(icu::Locale const&, UNumberFormatStyle, signed char, UErrorCode&) + 1600
17  libicucore.A.dylib                     0x181f489e8 icu::LocaleCacheKey<icu::SharedNumberFormat>::createObject(void const*, UErrorCode&) const + 84
18  libicucore.A.dylib                     0x181e6dae0 icu::UnifiedCache::_get(icu::CacheKeyBase const&, icu::SharedObject const*&, void const*, UErrorCode&) const + 140
19  libicucore.A.dylib                     0x181f495d0 0x181dbd000 + 1623504
20  libicucore.A.dylib                     0x181f48b10 0x181dbd000 + 1620752
21  libicucore.A.dylib                     0x181f4864c icu::NumberFormat::createInstance(icu::Locale const&, UNumberFormatStyle, UErrorCode&) + 92
22  libicucore.A.dylib                     0x181dcacf4 icu::SimpleDateFormat::initialize(icu::Locale const&, UErrorCode&) + 544
23  libicucore.A.dylib                     0x181dc6030 icu::SimpleDateFormat::construct(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 1952
24  libicucore.A.dylib                     0x181dc5838 icu::SimpleDateFormat::SimpleDateFormat(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 160
25  libicucore.A.dylib                     0x181dc5720 icu::DateFormat::create(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&) + 144
26  libicucore.A.dylib                     0x181dc5590 udat_open + 392
27  CoreFoundation                         0x18049f540 __cficu_udat_open + 68
28  CoreFoundation                         0x1803c3d68 __ResetUDateFormat + 484
29  CoreFoundation                         0x1803c367c __CreateCFDateFormatter + 320
30  CoreFoundation                         0x18049b4c0 -[NSDate descriptionWithLocale:] + 96
31  libxamarin-dotnet-debug.dylib          0x1129fcb8c xamarin_dyn_objc_msgSend + 160
32  newios                                 0x109125ab8 wrapper_managed_to_native_ObjCRuntime_Messaging_NativeHandle_objc_msgSend_NativeHandle_intptr_intptr_ObjCRuntime_NativeHandle + 168
33  newios                                 0x10843723c Foundation_NSDate_DescriptionWithLocale_Foundation_NSLocale + 140 (NSDate.g.cs:173)
34  newios                                 0x104f5a504 newios_AppDelegate_FinishedLaunching_UIKit_UIApplication_Foundation_NSDictionary + 500 (AppDelegate.cs:17)

Full crash report: https://gist.github.com/rolfbjarne/9fcedeb59d0521c4c9bb931056bba15c

Regression?

Yes. Fortunately it seems to only affect the simulator, and not device.

Known Workarounds

Disable globalization and make the app link mono statically works:

<PropertyGroup>
  <_LibXamarinLinkMode>static</_LibXamarinLinkMode>
  <_LibMonoLinkMode>static</_LibMonoLinkMode>
  <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<Target Name="_FixMonoLinkMode" AfterTargets="_MonoReadAvailableComponentsManifest">
  <ItemGroup>
    <_MonoRuntimeComponentLinking Remove="dynamic" />
    <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" />
  </ItemGroup>
</Target>

Configuration

$ dotnet --info
.NET SDK:
 Version:           8.0.100
 Commit:            57efcf1350
 Workload version:  8.0.100-manifests.5638171e

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  14.4
 OS Platform: Darwin
 RID:         osx-arm64
 Base Path:   /usr/local/share/dotnet/sdk/8.0.100/

.NET workloads installed:
 Workload version: 8.0.100-manifests.5638171e
 [ios]
   Installation Source: SDK 8.0.100
   Manifest Version:    17.2.8022/8.0.100
   Manifest Path:       /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.ios/17.2.8022/WorkloadManifest.json
   Install Type:        FileBased

Host:
  Version:      8.0.0
  Architecture: arm64
  Commit:       5535e31a71

.NET SDKs installed:
  8.0.100 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  x64   [/usr/local/share/dotnet/x64]
    registered at [/etc/dotnet/install_location_x64]

Environment variables:
  Not set

global.json file:
  Not found

Other information

No response

rolfbjarne commented 7 months ago

CC @steveisok

This completely breaks the simulator for us, so it's rather urgent to get it fixed (and any fixes would have to be backported to .NET 8)

ghost commented 7 months ago

Tagging subscribers to this area: @dotnet/area-system-globalization See info in area-owners.md if you want to be subscribed.

Issue Details
### Description App crashes when iOS starts using its own ICU code. I'm guessing it's because of a symbol clash with Mono's ICU symbols. ### Reproduction Steps 1. Install Xcode 15.3 beta 3. 2. Create a new iOS project: `dotnet new ios` 3. Add this to FinishedLaunching in AppDelegate.cs: ```cs var date = NSDate.Now; var locale = NSLocale.SystemLocale; var str = date.DescriptionWithLocale (locale); ``` 4. Run in an iOS 17.4 simulator Note: an iOS 17.2 simulator works just fine. ### Expected behavior No crash. ### Actual behavior Crash: ``` Thread 0 Crashed:: tid_103 Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x1129293b0 __pthread_kill + 8 1 libsystem_pthread.dylib 0x112557130 pthread_kill + 256 2 libsystem_c.dylib 0x1801655c0 abort + 104 3 libmonosgen-2.0.dylib 0x113316bcc sigabrt_signal_handler.cold.1 + 48 4 libmonosgen-2.0.dylib 0x113043a60 sigabrt_signal_handler + 196 5 libsystem_platform.dylib 0x1123237e0 _sigtramp + 52 6 libsystem_pthread.dylib 0x112557130 pthread_kill + 256 7 libsystem_c.dylib 0x1801655c0 abort + 104 8 libsystem_malloc.dylib 0x1801e378c malloc_vreport + 900 9 libsystem_malloc.dylib 0x1801e3950 malloc_report + 60 10 libsystem_malloc.dylib 0x1801d78a0 find_zone_and_free + 456 11 libicucore.A.dylib 0x181dbf2a0 icu::Locale::setToBogus() + 48 12 libicucore.A.dylib 0x181dc0c44 icu::Locale::operator=(icu::Locale const&) + 36 13 libicucore.A.dylib 0x181f2e5f4 icu::number::LocalizedNumberFormatter::LocalizedNumberFormatter(icu::number::impl::MacroProps&&, icu::Locale const&) + 212 14 libicucore.A.dylib 0x181eda738 icu::DecimalFormat::touch(UErrorCode&) + 204 15 libicucore.A.dylib 0x181edade8 icu::DecimalFormat::DecimalFormat(icu::UnicodeString const&, icu::DecimalFormatSymbols*, UNumberFormatStyle, UErrorCode&) + 328 16 libicucore.A.dylib 0x181f491b0 icu::NumberFormat::makeInstance(icu::Locale const&, UNumberFormatStyle, signed char, UErrorCode&) + 1600 17 libicucore.A.dylib 0x181f489e8 icu::LocaleCacheKey::createObject(void const*, UErrorCode&) const + 84 18 libicucore.A.dylib 0x181e6dae0 icu::UnifiedCache::_get(icu::CacheKeyBase const&, icu::SharedObject const*&, void const*, UErrorCode&) const + 140 19 libicucore.A.dylib 0x181f495d0 0x181dbd000 + 1623504 20 libicucore.A.dylib 0x181f48b10 0x181dbd000 + 1620752 21 libicucore.A.dylib 0x181f4864c icu::NumberFormat::createInstance(icu::Locale const&, UNumberFormatStyle, UErrorCode&) + 92 22 libicucore.A.dylib 0x181dcacf4 icu::SimpleDateFormat::initialize(icu::Locale const&, UErrorCode&) + 544 23 libicucore.A.dylib 0x181dc6030 icu::SimpleDateFormat::construct(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 1952 24 libicucore.A.dylib 0x181dc5838 icu::SimpleDateFormat::SimpleDateFormat(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 160 25 libicucore.A.dylib 0x181dc5720 icu::DateFormat::create(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&) + 144 26 libicucore.A.dylib 0x181dc5590 udat_open + 392 27 CoreFoundation 0x18049f540 __cficu_udat_open + 68 28 CoreFoundation 0x1803c3d68 __ResetUDateFormat + 484 29 CoreFoundation 0x1803c367c __CreateCFDateFormatter + 320 30 CoreFoundation 0x18049b4c0 -[NSDate descriptionWithLocale:] + 96 31 libxamarin-dotnet-debug.dylib 0x1129fcb8c xamarin_dyn_objc_msgSend + 160 32 newios 0x109125ab8 wrapper_managed_to_native_ObjCRuntime_Messaging_NativeHandle_objc_msgSend_NativeHandle_intptr_intptr_ObjCRuntime_NativeHandle + 168 33 newios 0x10843723c Foundation_NSDate_DescriptionWithLocale_Foundation_NSLocale + 140 (NSDate.g.cs:173) 34 newios 0x104f5a504 newios_AppDelegate_FinishedLaunching_UIKit_UIApplication_Foundation_NSDictionary + 500 (AppDelegate.cs:17) ``` Full crash report: https://gist.github.com/rolfbjarne/9fcedeb59d0521c4c9bb931056bba15c ### Regression? Yes. Fortunately it seems to only affect the simulator, and not device. ### Known Workarounds Disable globalization and make the app link mono statically works: ```xml <_LibXamarinLinkMode>static <_LibMonoLinkMode>static true <_MonoRuntimeComponentLinking Remove="dynamic" /> <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" /> ``` ### Configuration ```shell $ dotnet --info .NET SDK: Version: 8.0.100 Commit: 57efcf1350 Workload version: 8.0.100-manifests.5638171e Runtime Environment: OS Name: Mac OS X OS Version: 14.4 OS Platform: Darwin RID: osx-arm64 Base Path: /usr/local/share/dotnet/sdk/8.0.100/ .NET workloads installed: Workload version: 8.0.100-manifests.5638171e [ios] Installation Source: SDK 8.0.100 Manifest Version: 17.2.8022/8.0.100 Manifest Path: /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.ios/17.2.8022/WorkloadManifest.json Install Type: FileBased Host: Version: 8.0.0 Architecture: arm64 Commit: 5535e31a71 .NET SDKs installed: 8.0.100 [/usr/local/share/dotnet/sdk] .NET runtimes installed: Microsoft.AspNetCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Other architectures found: x64 [/usr/local/share/dotnet/x64] registered at [/etc/dotnet/install_location_x64] Environment variables: Not set global.json file: Not found ``` ### Other information _No response_
Author: rolfbjarne
Assignees: -
Labels: `area-System.Globalization`, `untriaged`, `os-ios`
Milestone: -
tarekgh commented 7 months ago

CC @akoeplinger

vitek-karas commented 7 months ago

/cc @matouskozak @ivanpovazan

lewing commented 7 months ago

@rolfbjarne @tarekgh @vitek-karas this is net8 so it isn't using hybrid globalization

steveisok commented 7 months ago

CC @steveisok

This completely breaks the simulator for us, so it's rather urgent to get it fixed (and any fixes would have to be backported to .NET 8)

Weird, I'm mentioned, but got no notification of this. @rolfbjarne confirming this is off of a .net 8 runtime?

tarekgh commented 7 months ago

@lewing I didn't claim it is from hybird globalization :smile:

looking at the stack

24  libicucore.A.dylib                     0x181dc5838 icu::SimpleDateFormat::SimpleDateFormat(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 160
25  libicucore.A.dylib                     0x181dc5720 icu::DateFormat::create(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&) + 144
26  libicucore.A.dylib                     0x181dc5590 udat_open + 392
27  CoreFoundation                         0x18049f540 __cficu_udat_open + 68
28  CoreFoundation                         0x1803c3d68 __ResetUDateFormat + 484
29  CoreFoundation                         0x1803c367c __CreateCFDateFormatter + 320
30  CoreFoundation                         0x18049b4c0 -[NSDate descriptionWithLocale:] + 96
31  libxamarin-dotnet-debug.dylib          0x1129fcb8c xamarin_dyn_objc_msgSend + 160

It is the calls to the CoreFoundation. I believe @steveisok is familiar with that stack. Something in the code https://github.com/dotnet/runtime/blob/62304a6d7085e32672ec988835eab41d89b82e25/src/native/libs/System.Globalization.Native/pal_locale.m#L96

mkhamoyan commented 7 months ago

looking at the stack

24  libicucore.A.dylib                       0x181dc5838 icu::SimpleDateFormat::SimpleDateFormat(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 160
25  libicucore.A.dylib                       0x181dc5720 icu::DateFormat::create(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&) + 144
26  libicucore.A.dylib                       0x181dc5590 udat_open + 392
27  CoreFoundation                           0x18049f540 __cficu_udat_open + 68
28  CoreFoundation                           0x1803c3d68 __ResetUDateFormat + 484
29  CoreFoundation                           0x1803c367c __CreateCFDateFormatter + 320
30  CoreFoundation                           0x18049b4c0 -[NSDate descriptionWithLocale:] + 96
31  libxamarin-dotnet-debug.dylib            0x1129fcb8c xamarin_dyn_objc_msgSend + 160

It is the calls to the CoreFoundation. I believe @steveisok is familiar with that stack. Something in the code

Calls to CoreFoundation are because of this block in AppDelegate.cs.

var date = NSDate.Now;
var locale = NSLocale.SystemLocale;
var str = date.DescriptionWithLocale (locale);

Most of the functions from runtime/src/native/libs/System.Globalization.Native/pal_locale.m will not be used in described scenario , only some of them like https://github.com/dotnet/runtime/blob/62304a6d7085e32672ec988835eab41d89b82e25/src/native/libs/System.Globalization.Native/pal_locale.m#L17 but from stacktrace these functions are not called.

rolfbjarne commented 7 months ago

CC @steveisok This completely breaks the simulator for us, so it's rather urgent to get it fixed (and any fixes would have to be backported to .NET 8)

Weird, I'm mentioned, but got no notification of this. @rolfbjarne confirming this is off of a .net 8 runtime?

Confirmed, this is with stable versions of everything (except Xcode).

steveisok commented 7 months ago

This is strange. This seems to be bypassing our globalization PAL. If true, that's unexpected and likely some kind of clash as @rolfbjarne suggested.

@rolfbjarne am I correct in seeing that the objc bindings are bypassing runtime?

rolfbjarne commented 7 months ago

This is strange. This seems to be bypassing our globalization PAL. If true, that's unexpected and likely some kind of clash as @rolfbjarne suggested.

@rolfbjarne am I correct in seeing that the objc bindings are bypassing runtime?

I'm not really sure what you mean. Our Objective-C bindings call iOS APIs, in this case in particular, [NSDate descriptionWithLocale:]. I see no reason for NSDate to call anything in the runtime's globalization PAL.

steveisok commented 7 months ago

I'm not really sure what you mean. Our Objective-C bindings call iOS APIs, in this case in particular, [NSDate descriptionWithLocale:]. I see no reason for NSDate to call anything in the runtime's globalization PAL.

That's good enough. You're confirming what I thought. I'm not sure exactly what to do here. I wonder if it worked previously by luck? Perhaps the icu version on that simulator has changed?

@akoeplinger since you've seen icu clashes like this before, any thoughts?

dalexsoto commented 7 months ago

Xcode 15.3 RC 1 is out and unfortunately we can still repro the issue

ivanpovazan commented 7 months ago

Perhaps the icu version on that simulator has changed?

That might be it. Looking at the difference between versions:

diff \
/Applications/Xcode_15.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/libicucore.A.tbd \
/Applications/Xcode_15.2.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/libicucore.A.tbd

shows:

< current-version: 74.1
---
> current-version: 72.1

On the other hand, our latest Microsoft.NETCore.Runtime.ICU.Transport 9.0.0-preview.3.24123.1 seems to include: ICU_version = 68.2.0.9

akoeplinger commented 7 months ago

This is pretty weird, according to the stacktrace this called into the system ICU libicucore.A.dylib since we don't ship a .dylib for icu.

If I had to guess it's maybe using our uprv_free in https://github.com/unicode-org/icu/blob/2d029329c82c7792b985024b2bdab5fc7278fbc8/icu4c/source/common/locid.cpp#L2022-L2039 instead of theirs?

One workaround that I think might be acceptable risk-wise is to rename the exported symbols to have e.g. a dotnet_ prefix. There is some functionality in urename.h that could be used.

rolfbjarne commented 7 months ago

One workaround that I think might be acceptable risk-wise is to rename the exported symbols to have e.g. a dotnet_ prefix. There is some functionality in urename.h that could be used.

We did this numerous times in Mono.

rolfbjarne commented 7 months ago

@steveisok .NET 9 seems to be working fine

dalexsoto commented 7 months ago

@steveisok / @vitek-karas any news on this issue?

steveisok commented 7 months ago

One workaround that I think might be acceptable risk-wise is to rename the exported symbols to have e.g. a dotnet_ prefix. There is some functionality in urename.h that could be used.

@dalexsoto looks like we're going to try this approach. Unsure of an ETA at this time.

ivanpovazan commented 7 months ago

I managed to repro and @rolfbjarne thank you for providing the workaround:

<PropertyGroup>
  <_LibXamarinLinkMode>static</_LibXamarinLinkMode>
  <_LibMonoLinkMode>static</_LibMonoLinkMode>
  <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<Target Name="_FixMonoLinkMode" AfterTargets="_MonoReadAvailableComponentsManifest">
  <ItemGroup>
    <_MonoRuntimeComponentLinking Remove="dynamic" />
    <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" />
  </ItemGroup>
</Target>

Although the app seems to work with just forcing static linking (we don't have to additionally disable globalization via <InvariantGlobalization>true</InvariantGlobalization> as a workaround) which also hints there is a problem with the exported symbols

rolfbjarne commented 7 months ago

Xcode 15.3 is now stable, and the crash still happens.

vitek-karas commented 7 months ago

@matouskozak is actively working on this now.

dsmitchell commented 7 months ago

Thanks @rolfbjarne. This bug was a ** to try to work around. I began to suspect bad SDK installations on my machine.

Your workaround fails on my setup, however, unless I remove this line:

<_MonoRuntimeComponentLinking Remove="dynamic" />

Otherwise the build complains with:

/usr/local/share/dotnet/packs/Microsoft.NET.Runtime.MonoTargets.Sdk/7.0.17/Sdk/RuntimeComponentManifest.targets(5,5): Error: Value of _MonoRuntimeComponentLinking for 'iossimulator-x64' must be 'dynamic' or 'static' it is ''. Malformed runtime pack?

Anyway, what is the impact of this workaround on non-simulator builds for iOS devices? Should I add conditions to the targets?

EDIT: This isn't working for me when we need to include Xamarin.TestCloud.Agent and we use iossimulator-x64. I get this error:

dyld[80652]: Library not loaded: @rpath/libmono-component-debugger.dylib

EDIT 2: Ok, so the workaround works on NET8, but not for NET7, which also suffers from this crash. It would be nice if there was a similar workaround for NET7 as well

rolfbjarne commented 7 months ago

Anyway, what is the impact of this workaround on non-simulator builds for iOS devices? Should I add conditions to the targets?

It shouldn't change anything for device builds (static linking is the default for device builds).

dsmitchell commented 7 months ago

Anyway, what is the impact of this workaround on non-simulator builds for iOS devices? Should I add conditions to the targets?

It shouldn't change anything for device builds (static linking is the default for device builds).

Thank you, that is useful to know. I have settled on this update for NET8, which works with Xamarin.TestCloud.Agent (iossimulator-x64), but it does not work with NET7. Any ideas? I think maybe target names changed between 7 & 8

  <PropertyGroup>
    <_LibXamarinLinkMode>static</_LibXamarinLinkMode>
    <_LibMonoLinkMode>static</_LibMonoLinkMode>
  </PropertyGroup>
  <Target Name="_FixMonoLinkMode" AfterTargets="_MonoReadAvailableComponentsManifest">
    <ItemGroup>
      <_MonoRuntimeComponentLinking Remove="dynamic" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="ios-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-x64" />
    </ItemGroup>
  </Target>

NET7 will be necessary because the Xamarin.UITest package has trouble with NET8 simulator builds

rolfbjarne commented 7 months ago

but it does not work with NET7. Any ideas?

Any particular reason you can't use Xcode 15.2, or the iOS 17.2 simulator in Xcode 15.3?

This is only an issue with the iOS 17.4 simulator that comes with Xcode 15.3.

rolfbjarne commented 7 months ago

Anyway, what is the impact of this workaround on non-simulator builds for iOS devices? Should I add conditions to the targets?

It shouldn't change anything for device builds (static linking is the default for device builds).

Actually wait, this like will change things for device builds:

<InvariantGlobalization>true</InvariantGlobalization>

so you should condition that on the simulator (or see if removing it altogether still works).

rolfbjarne commented 7 months ago

Would you have any suggestions as to why this is happening?

You can probably remove this line:

<_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="ios-arm64" />
crsillerjp commented 7 months ago

Would you have any suggestions as to why this is happening?

You can probably remove this line:

<_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="ios-arm64" />

Somehow I deleted my post, my code was failing during packaing showing:

error : Value of _MonoRuntimeComponentLinking for 'ios-arm64' must be 'dynamic' or 'static' it is 'static;static'.

Thank you, that makes sense, no need to apply it to ios-arm64 since I just want to deploy to simulator.

divil5000 commented 7 months ago

We are also seeing similar with our iOS app deployed in production on macOS 14.4. Stack trace below. Do you think it's the same thing @rolfbjarne ? Interestingly, it's happening when we try to show a date/time picker UI element.

Thread 0 Crashed:: tid_103 Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x189d4aa60 pthread_kill + 8 1 libsystem_pthread.dylib 0x189d82c20 pthread_kill + 288 2 libsystem_c.dylib 0x189c8fa20 abort + 180 3 AppName 0x1067e5748 0x104eb4000 + 26416968 4 AppName 0x1067839b0 0x104eb4000 + 26016176 5 libsystem_platform.dylib 0x189db3584 _sigtramp + 56 6 libsystem_pthread.dylib 0x189d82c20 pthread_kill + 288 7 libsystem_c.dylib 0x189c8fa20 abort + 180 8 libsystem_malloc.dylib 0x189b9faa8 malloc_vreport + 896 9 libsystem_malloc.dylib 0x189ba3114 malloc_report + 64 10 libsystem_malloc.dylib 0x189bbd494 find_zone_and_free + 528 11 libicucore.A.dylib 0x18cef7edc icu::Locale::setToBogus() + 52 12 libicucore.A.dylib 0x18cef8240 icu::Locale::operator=(icu::Locale const&) + 40 13 libicucore.A.dylib 0x18d05dd08 icu::number::LocalizedNumberFormatter::LocalizedNumberFormatter(icu::number::impl::MacroProps&&, icu::Locale const&) + 216 14 libicucore.A.dylib 0x18cfff7c0 icu::DecimalFormat::touch(UErrorCode&) + 240 15 libicucore.A.dylib 0x18d000024 icu::DecimalFormat::DecimalFormat(icu::UnicodeString const&, icu::DecimalFormatSymbols, UNumberFormatStyle, UErrorCode&) + 380 16 libicucore.A.dylib 0x18d07b718 icu::NumberFormat::makeInstance(icu::Locale const&, UNumberFormatStyle, signed char, UErrorCode&) + 1668 17 libicucore.A.dylib 0x18d07aec8 icu::LocaleCacheKey::createObject(void const, UErrorCode&) const + 88 18 libicucore.A.dylib 0x18cf82d08 icu::UnifiedCache::_get(icu::CacheKeyBase const&, icu::SharedObject const&, void const, UErrorCode&) const + 168 19 libicucore.A.dylib 0x18d07bcd8 0x18ced8000 + 1719512 20 libicucore.A.dylib 0x18d07b034 0x18ced8000 + 1716276 21 libicucore.A.dylib 0x18d07a930 icu::NumberFormat::createInstance(icu::Locale const&, UNumberFormatStyle, UErrorCode&) + 112 22 libicucore.A.dylib 0x18d0ca4bc icu::SimpleDateFormat::initialize(icu::Locale const&, UErrorCode&) + 572 23 libicucore.A.dylib 0x18d0c9f04 icu::SimpleDateFormat::construct(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 2024 24 libicucore.A.dylib 0x18d0cb234 icu::SimpleDateFormat::SimpleDateFormat(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) + 252 25 libicucore.A.dylib 0x18cff2254 icu::DateFormat::create(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&) + 172 26 libicucore.A.dylib 0x18d101fac udat_open + 396 27 CoreFoundation 0x189e9ee78 cficu_udat_open + 72 28 CoreFoundation 0x189e9e22c ResetUDateFormat + 516 29 CoreFoundation 0x189e9dffc __CreateCFDateFormatter + 324 30 Foundation 0x18afb53f4 -[NSDateFormatter _regenerateFormatter] + 264 31 Foundation 0x18afb5208 -[NSDateFormatter stringForObjectValue:] + 280 32 AppKit 0x18d92ce18 constructReferenceString_block_invoke + 352 33 AppKit 0x18d92cbac enumerateFormatSpecifiers + 624 34 AppKit 0x18dbf3a10 -[NSDatePickerCell(NSTextFieldWithStepperDatePickerInternal) _makeSubfieldsWithHandler:] + 332 35 AppKit 0x18d92c83c -[NSDatePickerCell(NSTextFieldWithStepperDatePickerInternal) _createSubfields] + 156 36 AppKit 0x18d92c2f8 -[NSDatePickerCell initTextCell:] + 292 37 AppKit 0x18d6de8bc -[NSControl initWithFrame:] + 128 38 AppKit 0x18d92c194 -[NSDatePicker initWithFrame:] + 48 39 UIKitMacHelper 0x1a30fc9bc -[UINSShadowDatePicker createBackingDatePickerIfNecessary] + 52 40 UIKitCore 0x1ba359cc8 -[_UIDatePickerMacCompactView setUpTextFieldsToMatchData:] + 56 41 UIKitCore 0x1ba358aa4 -[_UIDatePickerMacCompactView setData:] + 68 42 UIKitCore 0x1b9ea4ea8 -[UIDatePicker _installPickerView:updatingSize:] + 160 43 UIKitCore 0x1b9ea41f4 -[UIDatePicker initWithFrame:] + 340 44 AppName 0x1064ee0c0 0x104eb4000 + 23306432 45 AppName 0x105207338 0x104eb4000 + 3486520 46 AppName 0x106449968 0x104eb4000 + 22632808 47 AppName 0x106756870 0x104eb4000 + 25831536 48 AppName 0x1066a76d4 0x104eb4000 + 25114324 49 AppName 0x1066a9498 0x104eb4000 + 25121944 50 AppName 0x1067c27b8 0x104eb4000 + 26273720 51 AppName 0x1067c9890 0x104eb4000 + 26302608 52 UIKitCore 0x1ba076da0 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:deselectPrevious:performCustomSelectionAction:] + 1232 53 UIKitCore 0x1ba0770e8 -[UITableView _userSelectRowAtPendingSelectionIndexPath:animatedSelection:] + 296 54 UIKitCore 0x1b93ef52c -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 216 55 UIKitCore 0x1ba2ca3fc -[_UIAfterCACommitBlock run] + 72 56 UIKitCore 0x1ba2ca840 -[_UIAfterCACommitQueue flush] + 152 57 UIKitCore 0x1b91ee674 _runAfterCACommitDeferredBlocks + 496 58 UIKitCore 0x1b91ee400 _cleanUpAfterCAFlushAndRunDeferredBlocks + 100 59 UIKitCore 0x1b91ee324 _afterCACommitHandler + 32 60 CoreFoundation 0x189e61254 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 36 61 CoreFoundation 0x189e61140 __CFRunLoopDoObservers + 536 62 CoreFoundation 0x189e5fe58 CFRunLoopRunSpecific + 684 63 HIToolbox 0x1945fb000 RunCurrentEventLoopInMode + 292 64 HIToolbox 0x1945fac90 ReceiveNextEventCommon + 220 65 HIToolbox 0x1945fab94 _BlockUntilNextEventMatchingListInModeWithFilter + 76 66 AppKit 0x18d6b8970 _DPSNextEvent + 660 67 AppKit 0x18deaadec -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700 68 AppKit 0x18d6abcb8 -[NSApplication run] + 476 69 AppKit 0x18d682f54 NSApplicationMain + 880 70 AppKit 0x18d8d5610 _NSApplicationMainWithInfoDictionary + 24 71 UIKitMacHelper 0x1a30f10dc UINSApplicationMain + 972 72 UIKitCore 0x1b91dd9b4 UIApplicationMain + 148 73 AppName 0x1064e2790 xamarin_UIApplicationMain + 24 74 AppName 0x105205650 0x104eb4000 + 3479120 75 AppName 0x106432ee0 0x104eb4000 + 22540000 76 AppName 0x106756870 0x104eb4000 + 25831536 77 AppName 0x1066a5e24 0x104eb4000 + 25108004 78 AppName 0x1066ac6cc 0x104eb4000 + 25134796 79 AppName 0x10675b8dc 0x104eb4000 + 25852124 80 AppName 0x1064ed890 0x104eb4000 + 23304336 81 AppName 0x1067c1d20 0x104eb4000 + 26271008 82 dyld 0x1899fa0e0 start + 2360

rolfbjarne commented 7 months ago

We are also seeing similar with our iOS app deployed in production on macOS 14.4. Stack trace below. Do you think it's the same thing @rolfbjarne ? Interestingly, it's happening when we try to show a date/time picker UI element.

Yes, this looks like the same issue, but I've never seen it happen on device. Although what exactly do you mean by "iOS app deployed in production on macOS 14.4"?

filipnavara commented 7 months ago

Although what exactly do you mean by "iOS app deployed in production on macOS 14.4"?

Not the OP but you can upload iOS apps to the App Store / TestFlight and check a checkbox that allows their distribution to ARM64 Mac devices. I assume it's that scenario.

divil5000 commented 7 months ago

Yes, that's right. Our iOS app is available on the Mac App Store and with a few tweaks for running in that environment, it works really well.

rolfbjarne commented 7 months ago

Yes, that's right. Our iOS app is available on the Mac App Store and with a few tweaks for running in that environment, it works really well.

That's interesting, because:

  1. The workaround for the simulator is to link Mono statically.
  2. When building for device, linking Mono statically is the default.
  3. Yet, when running an iOS app built for device on macOS, it runs into this problem :/

I guess this means the fix is more urgent than we thought, because that means there's no known workaround for this new scenario.

divil5000 commented 7 months ago

We've had more than one customer complaining of the problem now (I presume macOS 14.4 is quite new) so it should be fairly straightforward to reproduce. Just instantiate and display a UIDatePicker.

// Not sure if the TimeZone has anything to do with it datePicker = new UIDatePicker() { TimeZone = Foundation.NSTimeZone.FromAbbreviation(@"UTC") };

dsmitchell commented 7 months ago

but it does not work with NET7. Any ideas?

Any particular reason you can't use Xcode 15.2, or the iOS 17.2 simulator in Xcode 15.3?

This is only an issue with the iOS 17.4 simulator that comes with Xcode 15.3.

So I downloaded Xcode 15.2 and installed the iOS 17.2 simulator, then built the app with NET7 and your workaround. It still crashes with the same bogus locale error, yet with NET8 works fine. I have a suspicion that maybe the fact that I have macOS 14.4 installed might be causing the error with NET7 and not necessarily the 17.2 or 17.4 simulator...

Any ideas how to get the workaround to work on NET7 as well?

Thanks

divil5000 commented 7 months ago

Our app is popular and widespread, and we cannot switch to net8.0 because a great many of our customers are stuck with iOS 10 due to their hardware. Why the decision was made to require iOS 11 with net8.0, I've no idea, but it seems arbitrary and it's quite limiting. A fix for this will definitely need to be backported to net7.0.

filipnavara commented 7 months ago

Why the decision was made to require iOS 11 with net8.0, I've no idea, but it seems arbitrary

It's not arbitrary at all. It's tied to Apple support policy. Last update for iOS 10 was released in 2019 and that was a special security update that was released after the OS was already deemed unsupported. It was also the last generation of iOS that supported 32-bit devices, so supporting it meant supporting an additional processor architecture (ARM32).

Per the official .NET lifecycle support policy .NET only supports platforms that are still officially supported by their respective vendors. Anything older may still be supported (as in "it runs") for some time but it's not guaranteed to receive fixes (and likely won't receive them).

From practical standpoint, supporting newer iOS versions requires new SDKs and Xcode versions. Old iOS version support gets dropped from Xcode, so in many cases it's not possible to support them. App Store uploads also enforce minimum SDK versions.

divil5000 commented 7 months ago

You haven't said anything to counter my assertion that it's arbitrary. With net7 I can target iOS 10, with net8 I can't. It's therefore a difference on the Microsoft side, not on the Apple side. When Apple no longer allow building or uploading apps that target iOS 10, fair enough, but this is Microsoft.

When, as in our case, a lot of customers buy the hardware specifically to run our app, we need to build the app for the operating system for as long as the manufacturer allows it.

Having been shipping this app since 2012 and the early days of Monotouch, I am well aware of the cycle of SDKs and Xcode versions.

rolfbjarne commented 7 months ago

When Apple no longer allow building or uploading apps that target iOS 10, fair enough, but this is Microsoft.

Xcode stopped supporting iOS 10 in 2022: https://developer.apple.com/news/upcoming-requirements/?id=06062022a.

divil5000 commented 7 months ago

I understand that they don't offer support for it. However we are happily releasing updates to our app every month or two, to this day, so the App Store still clearly supports it.

filipnavara commented 7 months ago

I understand that they don't offer support for it.

You don’t seem to understand that both Apple and Microsoft have support policies. These policies are in alignment. If you choose to ignore them then the burden is on you.

Furthermore, current minimum SDK requirement for App Store upload is iOS 16.1 SDK which shipped with Xcode 14.1 (https://developer.apple.com/news/upcoming-requirements/?id=04252023a). As Rolf pointed out, Xcode 14 doesn’t support 32-bit apps and as a consequence doesn’t support iOS 10 and the old devices. The requirement for SDK version is going to increase next month even further (https://developer.apple.com/news/upcoming-requirements/?id=04292024a):

ITMS-90725: SDK version issue - This app was built with the iOS 16.4 SDK. Starting April 29, 2024, all iOS and iPadOS apps must be built with the iOS 17 SDK or later, included in Xcode 15 or later, in order to be uploaded to App Store Connect or submitted for distribution.

divil5000 commented 7 months ago

I don't think they are alignment if Apple still allows products to be built for iOS 10 (supported or not) but Microsoft does not. I don't think it's fair to say we are ignoring any policies either; we simply support the oldest operating system that we are able to. I presume you are in the fortunate position of not needing to support so many customers using older hardware.

I am aware of the forthcoming change next month that will require apps to be built against the iOS 17 SDK. Are you saying that we will no longer be able to build for iOS 10, even with net7.0, at that point? The message is not clear.

filipnavara commented 7 months ago

I don't think they are alignment if Apple still allows products to be built for iOS 10 (supported or not) but Microsoft does not.

Once again, supported in this context means official support, ie. if something goes wrong you can go complain to Apple or Microsoft to fix it.

Supported as in "best of luck; we don't actively test these version but we also don't actively try to break them" is a different metric and you are on your own if you choose this path. As previously mentioned, maintaining iOS 10 support means maintaining build support for one more CPU architecture. Removing that is NOT an arbitrary decision. Likewise, the next minimum version bump to iOS 12.2 (.NET 9) is driven by the minimum iOS version that comes with a built-in Swift runtime.

I am not sure how you were able to upload apps with 32-bit iOS support to Apple App Store. Per the linked policy above, Apple was enforcing Xcode 14.1+ build tools since April 25, 2023 for any App Store uploads. I know from my own experience that they actually check this and reject uploads that don't match this policy. Since Xcode 14 dropped 32-bit support completely, uploading of 32-bit apps should not have worked for close to a year now.

divil5000 commented 7 months ago

Not only were, still are. We are still actively deploying to the App Store and to our many iOS 10 users. This is using Xcode 14.3. I haven't mentioned bitness (that was you) and I haven't said that we are still building for 32bit (we are not). However we have customers using iOS 10 on 64bit devices, who are unable to update to a newer version of iOS due to what Apple have made available for their hardware.

It isn't clear whether the soon-to-be-forced update to Xcode 15 will change the minimum version of iOS that we can target from 10. However, attempting to build our project targeting net8.0-ios results in an actual build error. That's not our familiar "you're on your own, best of luck" path, that's a "we have prevented this" path.

filipnavara commented 7 months ago

However we have customers using iOS 10 on 64bit devices, who are unable to update to a newer version of iOS due to what Apple have made available for their hardware.

Literally all devices with 64-bit processors that are supported on iOS 10 are also supported on iOS 11, including iPhone 5S and iPad Touch.

divil5000 commented 7 months ago

Then I have no explanation for why these customers appear unable to upgrade to iOS 11.

ivanpovazan commented 6 months ago

@dsmitchell one thing you can try is to expand the proposed workaround by adding two additional MSBuild targets in the following way:

  <PropertyGroup>
    <_LibXamarinLinkMode>static</_LibXamarinLinkMode>
    <_LibMonoLinkMode>static</_LibMonoLinkMode>
  </PropertyGroup>
  <Target Name="_FixMonoLinkMode" AfterTargets="_MonoReadAvailableComponentsManifest">
    <ItemGroup>
      <_MonoRuntimeComponentLinking Remove="dynamic" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="ios-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-x64" />
    </ItemGroup>
  </Target>

  <Target Name="_OverwriteReferencesLinkerFlags" BeforeTargets="_LinkNativeExecutable">
    <!-- Remove the `-u` prefix from `_ReferencesLinkerFlags` so we can give the output file to the platform linker -->
    <!-- NOTE: This step is actually also done after LinkNativeCode task, but we cannot intercept it differently -->
    <WriteLinesToFile SessionId="$(BuildSessionId)" File="$(_MtouchSymbolsList)" Lines="@(_ReferencesLinkerFlags->'%(Identity)'->Substring (2))" Overwrite="true" />

    <ItemGroup>
      <!-- Backup collected required symbols -->
      <_ReferencesLinkerFlagsBackup Include="@(_ReferencesLinkerFlags)" />

      <!-- Clear `_ReferencesLinkerFlags` to prevent required symbols to be passed in -u_symbolName format -->
      <_ReferencesLinkerFlags Remove="@(_ReferencesLinkerFlags)" />
      <!-- Instruct platform linker to only export required symbols -->
      <_ReferencesLinkerFlags Include="-exported_symbols_list" />
      <_ReferencesLinkerFlags Include="$(_MtouchSymbolsList)" />
    </ItemGroup>
  </Target>

  <Target Name="_RestoreReferencesLinkerFlags" AfterTargets="_LinkNativeExecutable">
    <ItemGroup>
      <_ReferencesLinkerFlags Remove="@(_ReferencesLinkerFlags)" />
      <_ReferencesLinkerFlags Include="@(_ReferencesLinkerFlagsBackup)" />
    </ItemGroup>
  </Target>

I tested this workaround on iossimulator with .net7 build and it solves the problem. It is not really a clean solution but seems to work.

The difference between .net7 and .net8 comes from the fact we are invoking the platform linker differently on .net7 compared to the newer releases. With https://github.com/xamarin/xamarin-macios/pull/18408 we started only exporting required symbols from the executable by utilizing -exported_symbols_list platform linker flag which will hide the clashing global ICU symbols from the mono runtime and make the initially proposed workaround valid for .net8.

However, in .net7 this isn't the case, as we are only instructing the platform linker to preserve the required symbols collected in _ReferencesLinkerFlags (via -u_symbolName) resulting with ICU symbols still being preserved/exported from the app which causes the symbol clash again.


@rolfbjarne @dalexsoto as this seems solvable on xamarin SDK side, we might want to consider backporting https://github.com/xamarin/xamarin-macios/pull/18408 to net7 instead, as the backport of the dotnet/runtime fix to net7 got rejected.

dsmitchell commented 6 months ago

@dsmitchell one thing you can try is to expand the proposed workaround by adding two additional MSBuild targets in the following way:

  <PropertyGroup>
    <_LibXamarinLinkMode>static</_LibXamarinLinkMode>
    <_LibMonoLinkMode>static</_LibMonoLinkMode>
  </PropertyGroup>
  <Target Name="_FixMonoLinkMode" AfterTargets="_MonoReadAvailableComponentsManifest">
    <ItemGroup>
      <_MonoRuntimeComponentLinking Remove="dynamic" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="ios-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-arm64" />
      <_MonoRuntimeComponentLinking Include="static" RuntimeIdentifier="iossimulator-x64" />
    </ItemGroup>
  </Target>

  <Target Name="_OverwriteReferencesLinkerFlags" BeforeTargets="_LinkNativeExecutable">
    <!-- Remove the `-u` prefix from `_ReferencesLinkerFlags` so we can give the output file to the platform linker -->
    <!-- NOTE: This step is actually also done after LinkNativeCode task, but we cannot intercept it differently -->
    <WriteLinesToFile SessionId="$(BuildSessionId)" File="$(_MtouchSymbolsList)" Lines="@(_ReferencesLinkerFlags->'%(Identity)'->Substring (2))" Overwrite="true" />

    <ItemGroup>
      <!-- Backup collected required symbols -->
      <_ReferencesLinkerFlagsBackup Include="@(_ReferencesLinkerFlags)" />

      <!-- Clear `_ReferencesLinkerFlags` to prevent required symbols to be passed in -u_symbolName format -->
      <_ReferencesLinkerFlags Remove="@(_ReferencesLinkerFlags)" />
      <!-- Instruct platform linker to only export required symbols -->
      <_ReferencesLinkerFlags Include="-exported_symbols_list" />
      <_ReferencesLinkerFlags Include="$(_MtouchSymbolsList)" />
    </ItemGroup>
  </Target>

  <Target Name="_RestoreReferencesLinkerFlags" AfterTargets="_LinkNativeExecutable">
    <ItemGroup>
      <_ReferencesLinkerFlags Remove="@(_ReferencesLinkerFlags)" />
      <_ReferencesLinkerFlags Include="@(_ReferencesLinkerFlagsBackup)" />
    </ItemGroup>
  </Target>

I tested this workaround on iossimulator with .net7 build and it solves the problem. It is not really a clean solution but seems to work.

The difference between .net7 and .net8 comes from the fact we are invoking the platform linker differently on .net7 compared to the newer releases. With xamarin/xamarin-macios#18408 we started only exporting required symbols from the executable by utilizing -exported_symbols_list platform linker flag which will hide the clashing global ICU symbols from the mono runtime and make the initially proposed workaround valid for .net8.

However, in .net7 this isn't the case, as we are only instructing the platform linker to preserve the required symbols collected in _ReferencesLinkerFlags (via -u_symbolName) resulting with ICU symbols still being preserved/exported from the app which causes the symbol clash again.

@rolfbjarne @dalexsoto as this seems solvable on xamarin SDK side, we might want to consider backporting xamarin/xamarin-macios#18408 to net7 instead, as the backport of the dotnet/runtime fix to net7 got rejected.

@ivanpovazan Thank you so much for this detailed explanation. It sounds promising, and I will try this out on my local setup. The reason why I am forced to also use NET7 for simulator is because of Xamarin.UITest v4.3.4 not supporting NET8 nor on-device testing at the moment

rolfbjarne commented 6 months ago

@ivanpovazan

@rolfbjarne @dalexsoto as this seems solvable on xamarin SDK side, we might want to consider backporting xamarin/xamarin-macios#18408 to net7 instead, as the backport of the dotnet/runtime fix to net7 got rejected.

That change caused some problems (https://github.com/xamarin/xamarin-macios/issues?q=is%3Aissue+sort%3Aupdated-desc+_ExportSymbolsExplicitly+), so it will probably not be backported (at least not with the new behavior on by default).