This will hopefully make it easier to diagnose these kinds of crashes:
Thread 0 Crashed:
0 libobjc.A.dylib 0x00000001a6f6e7f8 object_getClass + 48
1 MyTestDotNetApp.Net 0x0000000104b90a68 do_icall (interp.c:2273)
2 MyTestDotNetApp.Net 0x0000000104b8f838 do_icall_wrapper (interp.c:2361)
3 MyTestDotNetApp.Net 0x0000000104b85214 interp_exec_method (interp.c:3885)
4 MyTestDotNetApp.Net 0x0000000104b82de8 interp_runtime_invoke (interp.c:2122)
5 MyTestDotNetApp.Net 0x0000000104b4aedc mono_jit_runtime_invoke (mini-runtime.c:3650)
6 MyTestDotNetApp.Net 0x0000000104a8b874 mono_runtime_try_invoke (object.c:2415)
7 MyTestDotNetApp.Net 0x0000000104a8d8a0 mono_runtime_invoke (object.c:2464)
8 MyTestDotNetApp.Net 0x0000000104c42b68 native_to_managed_trampoline_68(objc_object*, objc_selector*, _MonoMethod**, objc_object*, unsigned int) (registrar.mm:4511)
9 MyTestDotNetApp.Net 0x0000000104c42a00 +[__NSObject_Disposer drain:] (registrar.mm:20968)
10 Foundation 0x00000001adc13b14 __NSThreadPerformPerform + 260
This happens because we try to access freed/invalid memory, but unfortunately
the crash report / stack trace does not contain any hint whatsoever about the
memory that triggered the crash.
By adding an opt-in to validate the memory for a given object, we might be
able to detect this crash in a few cases, and instead throw a managed
exception with much more information.
A project opts-in by setting `_ValidateObjectPointers=true` in the csproj.
Ref: https://github.com/xamarin/xamarin-macios/issues/19493
---------
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
Call mono_unhandled_exception to raise AppDomain.UnhandledException when
managed exceptions are unhandled.
Partial fix for #15252 (for MonoVM, still pending for CoreCLR, which
needs https://github.com/dotnet/runtime/issues/102730 fixed first).
Throw an exception for a condition we don't handle in the dynamic registrar:
calling a base Objective-C constructor (init method) with arguments. Our
current implementation to call the base Objective-C constructor doesn't handle
any arguments, so if the method actually takes any arguments, those will just
be random memory. In other words: a consistent exception is better than a
random invalid memory access.
We're using two different functions to atomically decrement a reference count,
the native `atomic_fetch_sub` and the managed `Interlocked.Decrement`.
Unfortunately the return value is not the same: `atomic_fetch_sub` returns the
original value before the subtraction, while `Interlocked.Decrement` returns
the subtracted value, while our code assumed the functions behaved the same.
This resulted in a memory leak, because we'd incorrectly expect `0` to be
returned from `atomic_fetch_sub` when the reference count reaches zero, and
thus not detect when the descriptor a block should be freed.
The fix is to update the expected return value from `atomic_fetch_sub` to be
`1` instead of `0`.
Fixes https://github.com/xamarin/xamarin-macios/issues/20503.
The stack trace from unhandled exception is now:
Unhandled managed exception: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') (System.ArgumentOutOfRangeException)
at System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].get_Item(Int32 index)
at CrashiOS.RootViewController.GetItem() in /Users/rolf/test/bugs/StackTraceIssue/CrashiOS/RootViewController.cs:line 19
at CrashiOS.RootViewController.<.ctor>b__1_0(Object _, EventArgs _) in /Users/rolf/test/bugs/StackTraceIssue/CrashiOS/RootViewController.cs:line 12
at UIKit.UIBarButtonItem.Callback.Call(NSObject sender) in xamarin-macios/src/UIKit/UIBarButtonItem.cs:line 33
--- End of stack trace from previous location ---
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle) in xamarin-macios/src/ObjCRuntime/Runtime.cs:line 2655
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in xamarin-macios/src/UIKit/UIApplication.cs:line 64
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in xamarin-macios/src/UIKit/UIApplication.cs:line 96
at Program.<Main>$(String[] args) in /Users/rolf/test/bugs/StackTraceIssue/CrashiOS/Main.cs:line 26
as opposed to:
Unhandled managed exception: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') (System.ArgumentOutOfRangeException)
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle)
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName)
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass)
at Program.<Main>$(String[] args) in /Users/rolf/test/bugs/StackTraceIssue/CrashiOS/Main.cs:line 26
Fixes https://github.com/xamarin/xamarin-macios/issues/19417.
Detect recursion when handling unhandled Objective-C exceptions, which can happen if:
* We install a handler for unhandled Objective-C exceptions.
* An unhandled Objective-C exception is caught.
* We convert the unhandled Objective-C exception to a managed exception, and throw that.
* Nobody handles the managed exception either, so we convert it to an Objective-C exception and throw that.
* We re-enter the unhandled Objective-C exception handler, and the cycle continues.
* Eventually the process crashes due to a stack overflow.
Fixes https://github.com/xamarin/xamarin-macios/issues/14796.
Once upon a time we needed to special case a higher min OS version that the
min OS version we supported for certain compiler/linker arguments, because we
used features not supported in the min OS version we supported.
That time has passed; in all cases our min OS version is now higher than the
special-cased min OS versions passed to native compilers/linkers, so we can
just use the actual min OS version we support.
It'll never be called from the generated code from the managed static
registrar, so there's no need to register it as a potential callback from
native code.
This makes the linker able to remove the Runtime.CreateDelegateProxy method
(and a few other methods as well) when using the managed static registrar (and
thus not warn about these methods doing un-trimmable stuff).
Contributes towards #10405.
It'll never be called from the generated code from the managed static
registrar, so there's no need to register it as a potential callback from
native code.
This makes the linker able to remove the Runtime.GetGenericMethodFromToken
method (and a few other methods as well).
Contributes towards #10405.
This pull request updates the following dependencies
## Coherency Updates
The following updates ensure that dependencies with a *CoherentParentDependency*
attribute were produced in a build used as input to the parent dependency's build.
See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview)
- **Coherency Updates**:
- **Microsoft.NET.ILLink.Tasks**: from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.AspNetCore.App.Ref**: from 9.0.0-alpha.1.23619.10 to 9.0.0-alpha.1.24060.28 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.NETCore.App.Ref**: from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26 (parent: Microsoft.Dotnet.Sdk.Internal)
- **Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport**: from 9.0.0-alpha.1.23617.2 to 9.0.0-alpha.1.24053.1 (parent: Microsoft.NETCore.App.Ref)
- **Microsoft.NETCore.App.Ref**: from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26 (parent: Microsoft.Dotnet.Sdk.Internal)
## From https://github.com/dotnet/installer
- **Subscription**: 3727984b-7a79-4ba3-37dd-08dbe6bddf31
- **Build**: 20240111.3
- **Date Produced**: January 11, 2024 11:13:41 AM UTC
- **Commit**: cc07296328b45ea6721d1c17662c3bc59aaff392
- **Branch**: refs/heads/main
- **Updates**:
- **Microsoft.Dotnet.Sdk.Internal**: [from 9.0.100-alpha.1.23619.5 to 9.0.100-alpha.1.24061.3][81]
- **Microsoft.NET.ILLink.Tasks**: [from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26][82]
- **Microsoft.AspNetCore.App.Ref**: [from 9.0.0-alpha.1.23619.10 to 9.0.0-alpha.1.24060.28][83]
- **Microsoft.NETCore.App.Ref**: [from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26][82]
- **Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport**: [from 9.0.0-alpha.1.23617.2 to 9.0.0-alpha.1.24053.1][84]
- **Microsoft.NETCore.App.Ref**: [from 9.0.0-alpha.1.23618.7 to 9.0.0-alpha.1.24060.26][82]
[81]: 1d730bb539...cc07296328
[82]: c282395b63...e5bab5fa31
[83]: 496e975d09...4ed85056f5
[84]: 13ad0749b9...5cda86493a
---------
Co-authored-by: Meri Khamoyan <merikhamoyan@microsoft.com>
Calling the direct functions instead of sending messages is slightly faster,
and additionally it may make some static analyzers think we've enabled ARC for
our Objective-C code (which we don't, because we need to manually manage
reference counting).
These direct functions aren't in any public header (they're in a private header),
but they're documented as part of ARC here: https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support,
and clang emits references to these methods from user code, so it should be safe for us to use them.
Fixes https://github.com/xamarin/xamarin-macios/issues/19413.
Fixed an issue where the C# class name was coming in with `,
AssemblyName` tacked on the end.
Fixed an issue where a class that had an entry in the map didn't have a
`class_ptr` which was causing an NRE.
Fixed a predicate for deciding when to mark the assembly for save.
Note - for an as yet undetermined reason, the linker is not picking up
that I'm marking the assembly for save, which is why the `true` test
cases are commented out.
This fixes issue 16671 https://github.com/xamarin/xamarin-macios/issues/16671
We're going to change the pack names to support multi-targeting, so ahead
of the pack name change I'm changing the existing logic to use a variable
for the pack name in most places (this will make the rename much easier and
simpler).
These changes should have no effect by themselves.
Since NativeAOT generates native libraries and executables that do not
rely on assemblies they were compiled from, all managed assemblies can
be excluded from the application bundle.
This reduces the size of the application bundle by `3,17Mb` (or ~19%
compared to the baseline)
| MAUI ios app | Base | This PR | diff (%) |
|--------------|-----------|-----------|----------|
| SOD (Mb) | 50,13 | 41,93 | -16,3% |
| .ipa (Mb) | 16,59 | 13,43 | -19% |
Fixes: https://github.com/xamarin/xamarin-macios/issues/18472
Change all null checking expressions to use 'is null' and 'is not null'
instead of '== null' and '!= null'.
This was mostly done with sed, so code can probably be improved in many
other ways with manual inspection, but that will come over time.
Also add code to the autoformat script to automatically fix these issues in the future.
The timeout can be given:
* By setting the __XAMARIN_DEBUG_CONNECT_TIMEOUT__ environment variable for the app when launching it.
* By passing the XamarinDebugConnectTimeout MSBuild property to 'dotnet run' or 'dotnet build /t:Run'.
* By setting the IOSDebugConnectTimeout MSBuild property at build time.
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1778177.