@@ -38,6 +38,11 @@ struct objspace {
3838 pthread_cond_t cond_world_started ;
3939 size_t start_the_world_count ;
4040
41+ struct {
42+ bool gc_thread_crashed ;
43+ char crash_msg [256 ];
44+ } crash_context ;
45+
4146 struct rb_gc_vm_context vm_context ;
4247
4348 unsigned int fork_hook_vm_lock_lev ;
@@ -169,6 +174,10 @@ rb_mmtk_block_for_gc(MMTk_VMMutatorThread mutator)
169174 pthread_cond_wait (& objspace -> cond_world_started , & objspace -> mutex );
170175 }
171176
177+ if (RB_UNLIKELY (objspace -> crash_context .gc_thread_crashed )) {
178+ rb_bug ("%s" , objspace -> crash_context .crash_msg );
179+ }
180+
172181 if (objspace -> measure_gc_time ) {
173182 struct timespec gc_end_time ;
174183 clock_gettime (CLOCK_MONOTONIC , & gc_end_time );
@@ -424,6 +433,32 @@ rb_mmtk_special_const_p(MMTk_ObjectReference object)
424433 return RB_SPECIAL_CONST_P (obj );
425434}
426435
436+ RBIMPL_ATTR_FORMAT (RBIMPL_PRINTF_FORMAT , 1 , 2 )
437+ static void
438+ rb_mmtk_gc_thread_bug (const char * msg , ...)
439+ {
440+ struct objspace * objspace = rb_gc_get_objspace ();
441+
442+ objspace -> crash_context .gc_thread_crashed = true;
443+
444+ va_list args ;
445+ va_start (args , msg );
446+ vsnprintf (objspace -> crash_context .crash_msg , sizeof (objspace -> crash_context .crash_msg ), msg , args );
447+ va_end (args );
448+
449+ rb_mmtk_resume_mutators ();
450+
451+ sleep (5 );
452+
453+ rb_bug ("rb_mmtk_gc_thread_bug" );
454+ }
455+
456+ static void
457+ rb_mmtk_gc_thread_panic_handler (void )
458+ {
459+ rb_mmtk_gc_thread_bug ("MMTk GC thread panicked" );
460+ }
461+
427462static void
428463rb_mmtk_mutator_thread_panic_handler (void )
429464{
@@ -454,6 +489,7 @@ MMTk_RubyUpcalls ruby_upcalls = {
454489 rb_mmtk_update_finalizer_table ,
455490 rb_mmtk_special_const_p ,
456491 rb_mmtk_mutator_thread_panic_handler ,
492+ rb_mmtk_gc_thread_panic_handler ,
457493};
458494
459495// Use max 80% of the available memory by default for MMTk
0 commit comments