Skip to content

Commit b5e54dc

Browse files
committed
Call rb_bug when Ruby mutator thread panics
This will allow the Ruby backtrace, memory mapping, etc. to be outputted when a Ruby mutator thread panics.
1 parent 97cb1a8 commit b5e54dc

5 files changed

Lines changed: 19 additions & 0 deletions

File tree

gc/mmtk/mmtk.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ rb_mmtk_special_const_p(MMTk_ObjectReference object)
355355
return RB_SPECIAL_CONST_P(obj);
356356
}
357357

358+
static void
359+
rb_mmtk_mutator_thread_panic_handler(void)
360+
{
361+
rb_bug("Ruby mutator thread panicked");
362+
}
363+
358364
// Bootup
359365
MMTk_RubyUpcalls ruby_upcalls = {
360366
rb_mmtk_init_gc_worker_thread,
@@ -374,6 +380,7 @@ MMTk_RubyUpcalls ruby_upcalls = {
374380
rb_mmtk_global_tables_count,
375381
rb_mmtk_update_finalizer_table,
376382
rb_mmtk_special_const_p,
383+
rb_mmtk_mutator_thread_panic_handler,
377384
};
378385

379386
// Use max 80% of the available memory by default for MMTk

gc/mmtk/mmtk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ typedef struct MMTk_RubyUpcalls {
6969
int (*global_tables_count)(void);
7070
void (*update_finalizer_table)(void);
7171
bool (*special_const_p)(MMTk_ObjectReference object);
72+
void (*mutator_thread_panic_handler)(void);
7273
} MMTk_RubyUpcalls;
7374

7475
typedef struct MMTk_RawVecOfObjRef {

gc/mmtk/src/abi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ pub struct RubyUpcalls {
314314
pub global_tables_count: extern "C" fn() -> c_int,
315315
pub update_finalizer_table: extern "C" fn(),
316316
pub special_const_p: extern "C" fn(object: ObjectReference) -> bool,
317+
pub mutator_thread_panic_handler: extern "C" fn(),
317318
}
318319

319320
unsafe impl Sync for RubyUpcalls {}

gc/mmtk/src/api.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ pub unsafe extern "C" fn mmtk_init_binding(
138138
upcalls: *const RubyUpcalls,
139139
weak_reference_dead_value: ObjectReference,
140140
) {
141+
crate::MUTATOR_THREAD_PANIC_HANDLER
142+
.set((unsafe { (*upcalls).clone() }).mutator_thread_panic_handler)
143+
.unwrap_or_else(|_| panic!("MUTATOR_THREAD_PANIC_HANDLER is already initialized"));
144+
141145
crate::set_panic_hook();
142146

143147
let builder = unsafe { Box::from_raw(builder) };

gc/mmtk/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ impl VMBinding for Ruby {
5555
type VMMemorySlice = RubyMemorySlice;
5656
}
5757

58+
/// The callback for mutator thread panic handler (which calls rb_bug to output
59+
/// debugging information such as the Ruby backtrace and memory maps).
60+
/// This is set before BINDING is set because mmtk_init could panic.
61+
pub static MUTATOR_THREAD_PANIC_HANDLER: OnceCell<extern "C" fn()> = OnceCell::new();
62+
5863
/// The singleton object for the Ruby binding itself.
5964
pub static BINDING: OnceCell<RubyBinding> = OnceCell::new();
6065

@@ -132,6 +137,7 @@ pub(crate) fn set_panic_hook() {
132137
handle_gc_thread_panic(panic_info);
133138
} else {
134139
old_hook(panic_info);
140+
(crate::MUTATOR_THREAD_PANIC_HANDLER.get().expect("MUTATOR_THREAD_PANIC_HANDLER is not set"))();
135141
}
136142
}));
137143
}

0 commit comments

Comments
 (0)