[runtime] Fix conserving stack trace when re-throwing marshalled exceptions. Fixes #19417. (#20316)

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.
This commit is contained in:
Rolf Bjarne Kvinge 2024-03-18 15:02:12 +01:00 коммит произвёл GitHub
Родитель 72283a0818
Коммит d794245b42
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
1 изменённых файлов: 23 добавлений и 3 удалений

Просмотреть файл

@ -2279,10 +2279,30 @@ xamarin_process_nsexception_using_mode (NSException *ns_exception, bool throwMan
GCHandle handle;
if (exc_handle != NULL) {
GCHandle e_handle = [exc_handle getHandle];
GCHandle rethrow_exception_gchandle;
MONO_ENTER_GC_UNSAFE;
//
// We want to maintain the original stack trace of the exception, but unfortunately
// calling mono_runtime_set_pending_exception directly with the original exception will overwrite
// the original stack trace.
//
// The good news is that the managed ExceptionDispatchInfo class is able to capture
// a stack trace for an exception and show it later.
//
// The xamarin_rethrow_managed_exception method will use ExceptionDispatchInfo
// to throw an exception that contains the original stack trace, we will then capture that
// exception, and pass it to mono_runtime_set_pending_exception.
//
xamarin_rethrow_managed_exception (e_handle, &rethrow_exception_gchandle);
if (rethrow_exception_gchandle == INVALID_GCHANDLE) {
PRINT (PRODUCT ": Did not get a rethrow exception, will throw the original exception. The original stack trace will be lost.");
MonoObject *exc = xamarin_gchandle_get_target (e_handle);
handle = xamarin_gchandle_new (exc, false);
xamarin_mono_object_release (&exc);
} else {
handle = rethrow_exception_gchandle;
}
MONO_EXIT_GC_UNSAFE;
} else {
handle = xamarin_create_ns_exception (ns_exception, &exception_gchandle);