Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ pub extern "C" fn mmtk_gc_init(
// Make sure we initialize MMTk here
lazy_static::initialize(&SINGLETON);

// Hijack the panic hook to make sure that if we crash in the GC threads, the process aborts.
crate::set_panic_hook();

// Assert to make sure our fastpath allocation is correct.
{
// If the assertion failed, check the allocation fastpath in Julia
Expand Down
29 changes: 29 additions & 0 deletions mmtk/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ use crate::{BLOCK_FOR_GC, STW_COND, WORLD_HAS_STOPPED};
static GC_START: AtomicU64 = AtomicU64::new(0);
static CURRENT_GC_MAY_MOVE: AtomicBool = AtomicBool::new(true);

use std::collections::HashSet;
use std::sync::RwLock;
use std::thread::ThreadId;

lazy_static! {
static ref GC_THREADS: RwLock<HashSet<ThreadId>> = RwLock::new(HashSet::new());
}

pub(crate) fn register_gc_thread() {
let id = std::thread::current().id();
GC_THREADS.write().unwrap().insert(id);
}
pub(crate) fn unregister_gc_thread() {
let id = std::thread::current().id();
GC_THREADS.write().unwrap().remove(&id);
}
pub(crate) fn is_gc_thread() -> bool {
let id = std::thread::current().id();
GC_THREADS.read().unwrap().contains(&id)
}

pub struct VMCollection {}

impl Collection<JuliaVM> for VMCollection {
Expand Down Expand Up @@ -99,6 +120,11 @@ impl Collection<JuliaVM> for VMCollection {
.spawn(move || {
use mmtk::util::opaque_pointer::*;
use mmtk::util::Address;

// Remember this GC thread
register_gc_thread();

// Start the worker loop
let worker_tls = VMWorkerThread(VMThread(OpaquePointer::from_address(unsafe {
Address::from_usize(thread_id::get())
})));
Expand All @@ -107,6 +133,9 @@ impl Collection<JuliaVM> for VMCollection {
mmtk::memory_manager::start_worker(&SINGLETON, worker_tls, w)
}
}

// The GC thread quits somehow. Unresgister this GC thread
unregister_gc_thread();
});
}

Expand Down
34 changes: 34 additions & 0 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,37 @@ macro_rules! early_return_for_current_gc {
}
};
}

pub(crate) fn set_panic_hook() {
let old_hook = std::panic::take_hook();

std::panic::set_hook(Box::new(move |panic_info| {
if crate::collection::is_gc_thread() {
eprintln!("ERROR: An MMTk GC thread panicked. This is a bug.");
eprintln!("{panic_info}");

let bt = std::backtrace::Backtrace::capture();
match bt.status() {
std::backtrace::BacktraceStatus::Unsupported => {
eprintln!("Backtrace is unsupported.")
}
std::backtrace::BacktraceStatus::Disabled => {
eprintln!("Backtrace is disabled.");
eprintln!(
"run with `RUST_BACKTRACE=1` environment variable to display a backtrace"
);
}
std::backtrace::BacktraceStatus::Captured => {
eprintln!("{bt}");
}
s => {
eprintln!("Unknown backtrace status: {s:?}");
}
}

std::process::abort();
} else {
old_hook(panic_info);
}
}));
}