This libgc patch helped isolate the mono problem Index: libgc/mark.c =================================================================== --- libgc/mark.c (revision 45372) +++ libgc/mark.c (working copy) @@ -636,6 +666,9 @@ # endif current_p = mark_stack_top -> mse_start; descr = mark_stack_top -> mse_descr; + GC_printf2("process ptr %p: slot %d\n", current_p, + (mark_stack_top - mark_stack)); + retry: /* current_p and descr describe the current object. */ /* *mark_stack_top is vacant. */ @@ -647,6 +680,8 @@ switch(tag) { case GC_DS_LENGTH: + GC_printf1(" DS_LENGTH: 0x%x\n", descr); + /* Large length. */ /* Process part of the range to avoid pushing too much on the */ /* stack. */ @@ -676,6 +711,7 @@ limit = (word *)((char *)limit + sizeof(word) - ALIGNMENT); break; case GC_DS_BITMAP: + GC_printf1(" DS_BITMAP: 0x%x\n", descr); mark_stack_top--; descr &= ~GC_DS_TAGS; credit -= WORDS_TO_BYTES(WORDSZ/2); /* guess */ @@ -694,6 +730,7 @@ } continue; case GC_DS_PROC: + GC_printf1(" DS_PROC: 0x%x\n", descr); mark_stack_top--; credit -= GC_PROC_BYTES; mark_stack_top = @@ -702,6 +739,7 @@ mark_stack_limit, ENV(descr)); continue; case GC_DS_PER_OBJECT: + GC_printf1(" DS_PER_OBJECT: 0x%x\n", descr); if ((signed_word)descr >= 0) { /* Descriptor is in the object. */ descr = *(word *)((ptr_t)current_p + descr - GC_DS_PER_OBJECT); @@ -731,9 +769,20 @@ mark_stack_top--; continue; } + /* mono specific amazingly hackish hack */ + { + void *MonoClass = *(void **)(*(void **)current_p); + if (MonoClass) { + char *name = *(void **)((unsigned char *)MonoClass + 0x34); + GC_printf6(" Object of type '%s' vtable %p class %p currentp %p has size %d slot %d on stack\n", + name, *(void **)current_p, MonoClass, current_p, descr, (mark_stack_top - mark_stack)); + } + } + goto retry; } } else /* Small object with length descriptor */ { + GC_printf1(" DS_SMALL_PER_OBJECT: 0x%x\n", descr); mark_stack_top--; limit = (word *)(((ptr_t)current_p) + (word)descr); } Index: libgc/include/private/gc_priv.h =================================================================== --- libgc/include/private/gc_priv.h (revision 45372) +++ libgc/include/private/gc_priv.h (working copy) @@ -14,7 +14,9 @@ * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. */ +#define GC_ASSERTIONS + # ifndef GC_PRIVATE_H # define GC_PRIVATE_H @@ -171,7 +172,8 @@ /* whether or not the block was found to be empty */ /* during the reclaim phase. Typically generates */ /* about one screenful per garbage collection. */ -#undef PRINTBLOCKS +#define PRINTBLOCKS +#undef SILENT #ifdef SILENT # ifdef PRINTSTATS Index: libgc/include/private/pthread_support.h =================================================================== --- libgc/include/private/pthread_support.h (revision 45372) +++ libgc/include/private/pthread_support.h (working copy) @@ -1,6 +1,8 @@ #ifndef GC_PTHREAD_SUPPORT_H #define GC_PTHREAD_SUPPORT_H +#define DEBUG_THREADS 1 + # include "private/gc_priv.h" # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \