Merge pull request #4503 from BrzVlad/fix-appdomain-unload
authorVlad Brezae <brezaevlad@gmail.com>
Fri, 24 Mar 2017 14:21:30 +0000 (16:21 +0200)
committerGitHub <noreply@github.com>
Fri, 24 Mar 2017 14:21:30 +0000 (16:21 +0200)
[runtime] Fix abort issues

1  2 
mono/metadata/object.c

diff --combined mono/metadata/object.c
index 3f3d6211638eb11c92b30ac7dd1f9bc5bf727e52,0a57d00bc66ddb7baf4a003e3c9b8ffb3f3056e3..41c481d41097c862b4a715f246f4fd922af40c62
@@@ -355,7 -355,7 +355,7 @@@ mono_runtime_class_init_full (MonoVTabl
        MonoNativeThreadId tid;
        int do_initialization = 0;
        MonoDomain *last_domain = NULL;
-       MonoException * pending_tae = NULL;
+       gboolean pending_tae = FALSE;
  
        error_init (error);
  
  
                mono_threads_begin_abort_protected_block ();
                mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, error);
-               gboolean got_pending_interrupt = mono_threads_end_abort_protected_block ();
+               mono_threads_end_abort_protected_block ();
  
                //exception extracted, error will be set to the right value later
                if (exc == NULL && !mono_error_ok (error))//invoking failed but exc was not set
                mono_coop_cond_broadcast (&lock->cond);
                mono_type_init_unlock (lock);
  
-               //This can happen if the cctor self-aborts
-               if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class)
-                       pending_tae = exc;
-               //TAEs are blocked around .cctors, they must escape as soon as no cctor is left to run.
-               if (!pending_tae && got_pending_interrupt)
-                       pending_tae = mono_thread_try_resume_interruption ();
+               /*
+                * This can happen if the cctor self-aborts. We need to reactivate tae
+                * (next interruption checkpoint will throw it) and make sure we won't
+                * throw tie for the type.
+                */
+               if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class) {
+                       pending_tae = TRUE;
+                       mono_thread_resume_interruption (FALSE);
+               }
        } else {
                /* this just blocks until the initializing thread is done */
                mono_type_init_lock (lock);
                vtable->initialized = 1;
        mono_type_initialization_unlock ();
  
-       //TAE wins over TIE
-       if (pending_tae)
-               mono_error_set_exception_instance (error, pending_tae);
-       else if (vtable->init_failed) {
+       /* If vtable init fails because of TAE, we don't throw TIE, only the TAE */
+       if (vtable->init_failed && !pending_tae) {
                /* Either we were the initializing thread or we waited for the initialization */
                mono_error_set_exception_instance (error, get_type_init_exception_for_vtable (vtable));
                return FALSE;
@@@ -4830,12 -4830,10 +4830,12 @@@ invoke_array_extract_argument (MonoArra
                                                *has_byref_nullables = TRUE;
                                } else {
                                        /* MS seems to create the objects if a null is passed in */
 +                                      gboolean was_null = FALSE;
                                        if (!mono_array_get (params, MonoObject*, i)) {
                                                MonoObject *o = mono_object_new_checked (mono_domain_get (), mono_class_from_mono_type (t_orig), error);
                                                return_val_if_nok (error, NULL);
                                                mono_array_setref (params, i, o); 
 +                                              was_null = TRUE;
                                        }
  
                                        if (t->byref) {
                                        }
                                                
                                        result = mono_object_unbox (mono_array_get (params, MonoObject*, i));
 +                                      if (!t->byref && was_null)
 +                                              mono_array_setref (params, i, NULL);
                                }
                                break;
                        case MONO_TYPE_STRING: