Fix a race in the posix suspend code that would lead to a crash.
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 14 Feb 2013 23:39:32 +0000 (18:39 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 14 Feb 2013 23:39:32 +0000 (18:39 -0500)
* mono-threads-posix.c: If we get the suspend signal while the thread
is detaching, we end up with a non null thread info but a null jit info.
This leads to thread_state_init_from_sigctx returning false. The
solution on this case is not to crash, but to tell the suspender
that the current suspend attempt failed.

Fixes an intermittent crash on the linux bots.

mono/utils/mono-threads-posix.c
mono/utils/mono-threads.h

index be3837cd9c7ac86fc5735a3cf308cec09685c149..cc8b61d9d9c5afedff24cffab6e522d5d8ed6d9e 100644 (file)
@@ -93,10 +93,15 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context)
 
        ret = mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&current->suspend_state, context);
 
-       g_assert (ret);
+       /* thread_state_init_from_sigctx return FALSE if the current thread is detaching and suspend can't continue. */
+       current->suspend_can_continue = ret;
 
        MONO_SEM_POST (&current->suspend_semaphore);
-               
+
+       /* This thread is doomed, all we can do is give up and let the suspender recover. */
+       if (!ret)
+               return;
+
        while (MONO_SEM_WAIT (&current->resume_semaphore) != 0) {
                /*if (EINTR != errno) ABORT("sem_wait failed"); */
        }
@@ -195,7 +200,7 @@ mono_threads_core_suspend (MonoThreadInfo *info)
        while (MONO_SEM_WAIT (&info->suspend_semaphore) != 0) {
                /* g_assert (errno == EINTR); */
        }
-       return TRUE;
+       return info->suspend_can_continue;
 }
 
 gboolean
index f192dd70732e1e6fc42a06395bcad58941879ead..43dd376fe8b77ae70c2245222c472ff8d6a83325 100644 (file)
@@ -109,6 +109,7 @@ typedef struct {
 #if (defined(_POSIX_VERSION) || defined(__native_client__)) && !defined (__MACH__)
        MonoSemType suspend_semaphore;
        gboolean syscall_break_signal;
+       gboolean suspend_can_continue;
 #endif
 
        /*In theory, only the posix backend needs this, but having it on mach/win32 simplifies things a lot.*/