Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[runtime] Handle fatal managed exceptions a bit better in the runtime. #15029

Merged
merged 1 commit into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions runtime/monotouch-main.m
Original file line number Diff line number Diff line change
Expand Up @@ -443,26 +443,22 @@ - (void) memoryWarning: (NSNotification *) sender

if (xamarin_executable_name) {
assembly = xamarin_open_and_register (xamarin_executable_name, &exception_gchandle);
if (exception_gchandle != NULL)
xamarin_process_managed_exception_gchandle (exception_gchandle);
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while opening the main executable");
} else {
const char *last_slash = strrchr (argv [0], '/');
const char *basename = last_slash ? last_slash + 1 : argv [0];
char *aname = xamarin_strdup_printf ("%s.exe", basename);

assembly = xamarin_open_and_register (aname, &exception_gchandle);
xamarin_free (aname);

if (exception_gchandle != NULL)
xamarin_process_managed_exception_gchandle (exception_gchandle);
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while opening an assembly");
}

if (xamarin_supports_dynamic_registration) {
MonoReflectionAssembly *rassembly = mono_assembly_get_object (mono_domain_get (), assembly);
xamarin_register_entry_assembly (rassembly, &exception_gchandle);
xamarin_mono_object_release (&rassembly);
if (exception_gchandle != NULL)
xamarin_process_managed_exception_gchandle (exception_gchandle);
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while opening the entry assembly");
}

DEBUG_LAUNCH_TIME_PRINT ("\tAssembly register time");
Expand Down
23 changes: 14 additions & 9 deletions runtime/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,17 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags;
xamarin_process_managed_exception_gchandle (gchandle);
}

void
xamarin_process_fatal_exception_gchandle (GCHandle gchandle, const char *message)
{
if (gchandle == INVALID_GCHANDLE)
return;

NSString *fatal_message = [NSString stringWithFormat:@"%s\n%@", message, xamarin_print_all_exceptions (gchandle)];
NSLog (@PRODUCT ": %@", fatal_message);
xamarin_assertion_message ([fatal_message UTF8String]);
}

// Because this function won't always return, it will take ownership of the GCHandle and free it.
void
xamarin_process_managed_exception_gchandle (GCHandle gchandle)
Expand Down Expand Up @@ -1136,7 +1147,7 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags;
while (xamarin_gc_pump) {
GCHandle exception_gchandle = INVALID_GCHANDLE;
xamarin_gc_collect (&exception_gchandle);
xamarin_process_managed_exception_gchandle (exception_gchandle);
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while running the GC in a loop");
MONO_ENTER_GC_SAFE;
usleep (1000000);
MONO_EXIT_GC_SAFE;
Expand Down Expand Up @@ -1300,16 +1311,10 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags;
#endif // defined(CORECLR_RUNTIME)

xamarin_bridge_call_runtime_initialize (&options, &exception_gchandle);
if (exception_gchandle != INVALID_GCHANDLE) {
NSLog (@PRODUCT ": An exception occurred when calling Runtime.Initialize:\n%@", xamarin_print_all_exceptions (exception_gchandle));
xamarin_assertion_message ("Can't continue if Runtime.Initialize fails.");
}
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while calling Runtime.Initialize");

xamarin_bridge_register_product_assembly (&exception_gchandle);
if (exception_gchandle != INVALID_GCHANDLE) {
NSLog (@PRODUCT ": An exception occurred when registering the product assembly:\n%@", xamarin_print_all_exceptions (exception_gchandle));
xamarin_assertion_message ("Can't continue if registering the product assembly fails.");
}
xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while registering the product assembly");

#if !defined (CORECLR_RUNTIME)
xamarin_install_mono_profiler (); // must be called before xamarin_install_nsautoreleasepool_hooks or xamarin_enable_new_refcount
Expand Down
1 change: 1 addition & 0 deletions runtime/xamarin/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ void xamarin_process_nsexception (NSException *exc);
void xamarin_process_nsexception_using_mode (NSException *ns_exception, bool throwManagedAsDefault, GCHandle *output_exception);
void xamarin_process_managed_exception (MonoObject *exc);
void xamarin_process_managed_exception_gchandle (GCHandle gchandle);
void xamarin_process_fatal_exception_gchandle (GCHandle gchandle, const char *message);
void xamarin_throw_product_exception (int code, const char *message);
GCHandle xamarin_create_product_exception (int code, const char *message);
GCHandle xamarin_create_product_exception_with_inner_exception (int code, GCHandle inner_exception_gchandle /* will be freed */, const char *message);
Expand Down