[Mono-bugs] [Bug 537764] Mono crashes on OS X Snow Leopard

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Wed Dec 2 15:40:26 EST 2009



--- Comment #18 from Laurent Etiemble <laurent.etiemble at gmail.com> 2009-12-02 20:40:17 UTC ---
Created an attachment (id=330599)
 --> (http://bugzilla.novell.com/attachment.cgi?id=330599)
Avoid re-registration of foreign threads on Darwin platforms

Here are the result of my investigations:

I have first try to solve the issue by modifying the way Monobjc plugs into the
Objective-C runtime. There were some success, but the crash did not go away. It
seems that the workaround did not catch all the paths. I don't think we can
achieve a correction this way.

So, I have investigated a bit more about the double-registration of foreign
threads. It appears that it already occurs in Leopard but the crash does not

Here is my understanding:
- When some managed code is called from native library, Mono registers the
current thread as foreign.
- In order to de-register the thread when it exits, Mono binds a destuctor
function (GC_thread_deregister_foreign) to a TSD (Thread Specific Data) key.
- When the foreign thread exits (pthread_exit), all the TSD are cleared and
their non-NULL destructor function are called. Mono de-register the foreign
- After the TSD are cleared, the Objective-C runtime sends a notification
(NSThreadWillExitNotification). Some code in Monobjc is invoked leading to a
native/managed call. The thread is re-registered as foreign.
- The GC_thread_deregister_foreign is re-bound to its TSD.
- On Leopard (Mac OS X 10.5), the TSD are cleared again thus leading the
re-registered thread to be re-de-registered.
- On Snow Leopard (Mac OS X 10.6), the TSD are not cleared in the same way thus
leaving the re-registered thread as is. The GC has now a stale reference on a
destroyed thread. As the order of the TSD destruction is unspecified, I assume
that it is the cause of the crash.

The first proposed patches aim at hiding the crash when a stale thread was
suspended. It was leaving the GC with some leaked bits.

The attached patch goes a step further. Instead of masking the result of the
double-registration, it avoids it. The trick used is to use a TSD mark on
foreign thread during the first register, so if the same thread is registered
again, the GC does nothing when it detects the mark. To avoid the result of the
unspecified order of the TSD destruction, we re-set the TSD mark in destructor
function (permitted by

Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.

More information about the mono-bugs mailing list