/** * mono_error_raise_exception: * @target_error: the exception to raise * * Raises the exception of @target_error. * Does nothing if @target_error has a success error code. * Aborts in case of a double fault. This happens when it can't recover from an error caused by trying * to construct the first exception object. * The error object @target_error is cleaned up. */ void mono_error_raise_exception (MonoError *target_error) { MonoException *ex = mono_error_convert_to_exception (target_error); if (ex) mono_raise_exception (ex); }
/* * Some of our objects may point to a different address than the address returned by GC_malloc() * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer. * This also means that in the callback we need to adjust the pointer to get back the real * MonoObject*. * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, * since that, too, can cause the underlying pointer to be offset. */ static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) { #if HAVE_BOEHM_GC guint offset = 0; MonoDomain *domain; if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); domain = obj->vtable->domain; #ifndef GC_DEBUG /* This assertion is not valid when GC_DEBUG is defined */ g_assert (GC_base (obj) == (char*)obj - offset); #endif if (mono_domain_is_unloading (domain) && (callback != NULL)) /* * Can't register finalizers in a dying appdomain, since they * could be invoked after the appdomain has been unloaded. */ return; mono_domain_finalizers_lock (domain); if (callback) g_hash_table_insert (domain->finalizable_objects_hash, obj, obj); else g_hash_table_remove (domain->finalizable_objects_hash, obj); mono_domain_finalizers_unlock (domain); GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL); #elif defined(HAVE_SGEN_GC) if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); /* * If we register finalizers for domains that are unloading we might * end up running them while or after the domain is being cleared, so * the objects will not be valid anymore. */ if (!mono_domain_is_unloading (obj->vtable->domain)) mono_gc_register_for_finalization (obj, callback); #endif }
void ves_icall_System_GC_register_ephemeron_array (MonoObject *array) { #ifdef HAVE_SGEN_GC if (!mono_gc_ephemeron_array_add (array)) mono_raise_exception (mono_object_domain (array)->out_of_memory_ex); #endif }
void ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj) { if (!obj) mono_raise_exception (mono_get_exception_argument_null ("obj")); object_register_finalizer (obj, mono_gc_run_finalize); }
MonoString * ves_icall_System_String_InternalIntern (MonoString *str) { MonoString *res; res = mono_string_intern(str); if (!res) mono_raise_exception (mono_domain_get ()->out_of_memory_ex); return res; }
gpointer mono_gc_out_of_memory (size_t size) { /* * we could allocate at program startup some memory that we could release * back to the system at this point if we're really low on memory (ie, size is * lower than the memory we set apart) */ mono_raise_exception (mono_domain_get ()->out_of_memory_ex); return NULL; }
MonoString * ves_icall_Mono_Runtime_GetNativeStackTrace (MonoException *exc) { char *trace; MonoString *res; if (!exc) mono_raise_exception (mono_get_exception_argument_null ("exception")); trace = mono_exception_get_native_backtrace (exc); res = mono_string_new (mono_domain_get (), trace); g_free (trace); return res; }
__stub void Test_TestClass_TestStaticMethod(void) { MonoException *exception; slow_path: sp_ensure_runtime(); FnTest_TestClass_TestStaticMethod = sp_get_method_thunk("Test.TestClass:TestStaticMethod()"); sp_rewrite_me(&&slow_path, &&fast_path); fast_path: FnTest_TestClass_TestStaticMethod(&exception); if (exception != NULL) { mono_raise_exception(exception); } }
void ves_icall_System_GC_SuppressFinalize (MonoObject *obj) { if (!obj) mono_raise_exception (mono_get_exception_argument_null ("obj")); /* delegates have no finalizers, but we register them to deal with the * unmanaged->managed trampoline. We don't let the user suppress it * otherwise we'd leak it. */ if (obj->vtable->klass->delegate) return; /* FIXME: Need to handle case where obj has COM Callable Wrapper * generated for it that needs cleaned up, but user wants to suppress * their derived object finalizer. */ object_register_finalizer (obj, NULL); }
__stub int Test_TestClass_TestStaticMethod2(void) { int result; MonoException *exception; slow_path: sp_ensure_runtime(); FnTest_TestClass_TestStaticMethod2 = sp_get_method_thunk("Test.TestClass:TestStaticMethod2()"); sp_rewrite_me(&&slow_path, &&fast_path); fast_path: result = FnTest_TestClass_TestStaticMethod2(&exception); if (exception != NULL) { mono_raise_exception(exception); return 0; } return result; }
/* * Some of our objects may point to a different address than the address returned by GC_malloc() * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer. * This also means that in the callback we need to adjust the pointer to get back the real * MonoObject*. * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, * since that, too, can cause the underlying pointer to be offset. */ static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) { MonoDomain *domain; if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); domain = obj->vtable->domain; #if HAVE_BOEHM_GC if (mono_domain_is_unloading (domain) && (callback != NULL)) /* * Can't register finalizers in a dying appdomain, since they * could be invoked after the appdomain has been unloaded. */ return; mono_domain_finalizers_lock (domain); if (callback) g_hash_table_insert (domain->finalizable_objects_hash, obj, obj); else g_hash_table_remove (domain->finalizable_objects_hash, obj); mono_domain_finalizers_unlock (domain); mono_gc_register_for_finalization (obj, callback); #elif defined(HAVE_SGEN_GC) /* * If we register finalizers for domains that are unloading we might * end up running them while or after the domain is being cleared, so * the objects will not be valid anymore. */ if (!mono_domain_is_unloading (domain)) { MONO_TRY_BLOCKING; mono_gc_register_for_finalization (obj, callback); MONO_FINISH_TRY_BLOCKING; } #endif }
__stub void *new_Test_TestClass2(int start) { MonoException *exception; MonoObject *obj; slow_path: sp_ensure_runtime(); Test_TestClass = mono_class_from_name(m_image, "Test", "TestClass"); Fnnew_Test_TestClass2 = sp_get_method_thunk("Test.TestClass:.ctor(int)"); sp_rewrite_me(&&slow_path, &&fast_path); fast_path: obj = mono_object_new(m_domain, Test_TestClass); Fnnew_Test_TestClass2(obj, start, &exception); if (exception != NULL) { mono_raise_exception(exception); return NULL; } return obj; }
/* Raises the exception of @error. Does nothing if @error has a success error code. Aborts in case of a double fault. This happens when it can't recover from an error caused by trying to construct the first exception object. The error object @error is cleaned up. */ void mono_error_raise_exception (MonoError *target_error) { MonoError error; MonoException *ex; if (mono_error_ok (target_error)) return; ex = mono_error_prepare_exception (target_error, &error); if (!mono_error_ok (&error)) { MonoError second_chance; /*Try to produce the exception for the second error. FIXME maybe we should log about the original one*/ ex = mono_error_prepare_exception (&error, &second_chance); g_assert (mono_error_ok (&second_chance)); /*We can't reasonable handle double faults, maybe later.*/ mono_error_cleanup (&error); } mono_error_cleanup (target_error); mono_raise_exception (ex); }
static void get_entropy_from_server (const char *path, guchar *buf, int len) { int file; gint ret; guint offset = 0; struct sockaddr_un egd_addr; file = socket (PF_UNIX, SOCK_STREAM, 0); if (file < 0) ret = -1; else { egd_addr.sun_family = AF_UNIX; strncpy (egd_addr.sun_path, path, sizeof(egd_addr.sun_path) - 1); egd_addr.sun_path [sizeof(egd_addr.sun_path)-1] = '\0'; ret = connect (file, (struct sockaddr *)&egd_addr, sizeof(egd_addr)); } if (ret == -1) { if (file >= 0) close (file); g_warning ("Entropy problem! Can't create or connect to egd socket %s", path); mono_raise_exception (mono_get_exception_execution_engine ("Failed to open egd socket")); } while (len > 0) { guchar request[2]; gint count = 0; request [0] = 2; /* block until daemon can return enough entropy */ request [1] = len < 255 ? len : 255; while (count < 2) { int sent = write (file, request + count, 2 - count); if (sent >= 0) count += sent; else if (errno == EINTR) continue; else { close (file); g_warning ("Send egd request failed %d", errno); mono_raise_exception (mono_get_exception_execution_engine ("Failed to send request to egd socket")); } } count = 0; while (count != request [1]) { int received; received = read(file, buf + offset, request [1] - count); if (received > 0) { count += received; offset += received; } else if (received < 0 && errno == EINTR) { continue; } else { close (file); g_warning ("Receive egd request failed %d", errno); mono_raise_exception (mono_get_exception_execution_engine ("Failed to get response from egd socket")); } } len -= request [1]; } close (file); }