From: Alexander Kyte Date: Fri, 8 May 2015 16:07:42 +0000 (-0400) Subject: [runtime] Make thread abort synchronous X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=632ddbf84dfc429e2f8f1aa0b5c4e1790f683f40;p=mono.git [runtime] Make thread abort synchronous Due to asynchronous abortion a crash is being seen on posix systems where the abort signal handler is having a data race and not exiting the suspend signal handler early. When it tries to make a state transition because of this, it cannot and it crashes. This fixes it by making it synchronous. --- diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c index 19fd8b7c12e..b74bf644870 100644 --- a/mono/utils/mono-threads-posix.c +++ b/mono/utils/mono-threads-posix.c @@ -452,6 +452,7 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context) if (current->syscall_break_signal) { current->syscall_break_signal = FALSE; THREADS_SUSPEND_DEBUG ("\tsyscall break for %p\n", current); + mono_threads_notify_initiator_of_abort (current); goto done; } @@ -582,7 +583,8 @@ mono_threads_core_abort_syscall (MonoThreadInfo *info) This signal should not be interpreted as a suspend request. */ info->syscall_break_signal = TRUE; - mono_threads_pthread_kill (info, abort_signal_num); + if (!mono_threads_pthread_kill (info, abort_signal_num)) + mono_threads_add_to_pending_operation_set (info); } gboolean diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index b720063ad63..f1b26bc1d40 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -64,7 +64,15 @@ static gboolean unified_suspend_enabled; /*abort at 1 sec*/ #define SLEEP_DURATION_BEFORE_ABORT 200 -static int suspend_posts, resume_posts, waits_done, pending_ops; +static int suspend_posts, resume_posts, abort_posts, waits_done, pending_ops; + +void +mono_threads_notify_initiator_of_abort (MonoThreadInfo* info) +{ + THREADS_SUSPEND_DEBUG ("[INITIATOR-NOTIFY-ABORT] %p\n", mono_thread_info_get_tid (info)); + MONO_SEM_POST (&suspend_semaphore); + InterlockedIncrement (&abort_posts); +} void mono_threads_notify_initiator_of_suspend (MonoThreadInfo* info) @@ -121,7 +129,8 @@ void mono_threads_begin_global_suspend (void) { g_assert (pending_suspends == 0); - THREADS_SUSPEND_DEBUG ("------ BEGIN GLOBAL OP sp %d rp %d wd %d po %d\n", suspend_posts, resume_posts, waits_done, pending_ops); + THREADS_SUSPEND_DEBUG ("------ BEGIN GLOBAL OP sp %d rp %d ap %d wd %d po %d\n", suspend_posts, resume_posts, + abort_posts, waits_done, pending_ops); mono_threads_core_begin_global_suspend (); } @@ -129,7 +138,8 @@ void mono_threads_end_global_suspend (void) { g_assert (pending_suspends == 0); - THREADS_SUSPEND_DEBUG ("------ END GLOBAL OP sp %d rp %d wd %d po %d\n", suspend_posts, resume_posts, waits_done, pending_ops); + THREADS_SUSPEND_DEBUG ("------ END GLOBAL OP sp %d rp %d ap %d wd %d po %d\n", suspend_posts, resume_posts, + abort_posts, waits_done, pending_ops); mono_threads_core_end_global_suspend (); } @@ -997,10 +1007,14 @@ mono_thread_info_abort_socket_syscall_for_close (MonoNativeThreadId tid) } mono_thread_info_suspend_lock (); + mono_threads_begin_global_suspend (); mono_threads_core_abort_syscall (info); + mono_threads_wait_pending_operations (); mono_hazard_pointer_clear (hp, 1); + + mono_threads_end_global_suspend (); mono_thread_info_suspend_unlock (); } diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h index eaefe4dec70..54f3e8b63d4 100644 --- a/mono/utils/mono-threads.h +++ b/mono/utils/mono-threads.h @@ -556,6 +556,11 @@ This tells the resume initiator that we completed resume duties and will return */ void mono_threads_notify_initiator_of_resume (THREAD_INFO_TYPE* info); +/* +This tells the resume initiator that we completed abort duties and will return to previous state. +*/ +void mono_threads_notify_initiator_of_abort (THREAD_INFO_TYPE* info); + /* Thread state machine functions */ typedef enum {