[Mono-dev] mono_jit_init called from non-main thread segfaults

Reiterer, Horst horst.reiterer at fabasoft.com
Wed Jan 18 08:52:50 EST 2006


Hi,

I embed Mono in a custom Apache module (Linux x86). If Mono is
initialized in a thread other than the main thread, e.g. an Apache
worker thread, the initialization process causes a segmentation fault
originating from GC initialization - pthread_push_all_stacks only takes
the main thread's stack into account. As a result, wrong arguments are
passed to GC_push_all_stack which in turn causes a segfault in
GC_push_all_eager.

This issue can be fixed using the patch below (only works with NPTL at
the very moment). What the new code does is checking if the
pthread_push_all_stacks caller is the main thread. If it isn't, the
stack address of the current thread is read using pthread_getattr_np and
pthread_attrgetstack. Otherwise, the behaviour remains unchanged.

Would you accept a fix along these lines? If yes, I'd be more than happy
to prepare a production-ready patch that is valid for both NPTL and
LinuxThreads. IMHO, it should be possible for a host to initialize Mono
at any point-in-time, from any thread. Being able to do so means that
the runtime can be initialized in a lazy manner.


Another problem I encountered while working on this is that the current
code base seems to assume that no attached thread blocks SIG_SUSPEND
(SIGXCPU on Linux), the signal used by the GC to suspend mutators. If
that assumption fails because code executed before modified the signal
mask, garbage collection will block indefinitely due to the fact that
not all mutators respond to the request for suspension. This issue could
IMHO be fixed by unblocking the signal in mono_thread_attach.

Cheers,

Horst.

--- mono-1.1.12.1/libgc/pthread_stop_world.c    2006-01-18
14:13:18.979146129 +0100
+++ mono-1.1.12.1-dev/libgc/pthread_stop_world.c        2006-01-18
14:12:50.586736171 +0100
@@ -9,6 +9,9 @@
 #include <errno.h>
 #include <unistd.h>

+#include <linux/unistd.h>
+_syscall0(pid_t,gettid)
+
 #if DEBUG_THREADS

 #ifndef NSIG
@@ -249,9 +252,18 @@
             hi = p -> stack_end;
             IF_IA64(bs_lo = p -> backing_store_end);
         } else {
-            /* The original stack. */
-            hi = GC_stackbottom;
-            IF_IA64(bs_lo = BACKING_STORE_BASE;)
+            if (gettid() != getpid()) {
+                size_t size;
+                pthread_attr_t attr;
+                pthread_getattr_np(p->id, &attr);
+                pthread_attr_getstack(&attr, &hi, &size);
+                hi += size;
+            }
+            else {
+                /* The original stack. */
+                hi = GC_stackbottom;
+                IF_IA64(bs_lo = BACKING_STORE_BASE;)
+            }
         }
         #if DEBUG_THREADS
             GC_printf3("Stack for thread 0x%lx = [%lx,%lx)\n",




More information about the Mono-devel-list mailing list