Skip to content

Commit

Permalink
Allow dereferencing a rooted Gc during collection
Browse files Browse the repository at this point in the history
Ordinarily, objects dropped during collections would only contain
unrooted Gc pointers.  But with `#[unsafe_ignore_trace]` it’s possible
to smuggle a rooted Gc pointer into the heap.  When we collect a
rooted Gc pointer, we need to dereference it in order to unroot its
contents.  This should be safe because the associated allocation
cannot have been collected while the Gc is rooted.

Fixes an “assertion failed: finalizer_safe()” panic in the included
test case (refs #52).

Signed-off-by: Anders Kaseorg <[email protected]>
  • Loading branch information
andersk committed Feb 5, 2023
1 parent de3769d commit 9752d3d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
4 changes: 2 additions & 2 deletions gc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ impl<T: ?Sized> Gc<T> {
#[inline]
fn inner_ptr(&self) -> *mut GcBox<T> {
// If we are currently in the dropping phase of garbage collection,
// it would be undefined behavior to dereference this pointer.
// it would be undefined behavior to dereference an unrooted Gc.
// By opting into `Trace` you agree to not dereference this pointer
// within your drop method, meaning that it should be safe.
//
// This assert exists just in case.
assert!(finalizer_safe());
assert!(finalizer_safe() || self.rooted());

unsafe { clear_root_bit(self.ptr_root.get()).as_ptr() }
}
Expand Down
12 changes: 12 additions & 0 deletions gc/tests/ignore_trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use gc::{force_collect, Finalize, Gc, Trace};

#[derive(Finalize, Trace)]
struct S(#[unsafe_ignore_trace] Gc<()>);

/// Using `#[unsafe_ignore_trace]` on a `Gc` may inhibit collection of
/// cycles through that `Gc`, but it should not result in panics.
#[test]
fn ignore_trace_gc() {
Gc::new(S(Gc::new(())));
force_collect();
}

0 comments on commit 9752d3d

Please sign in to comment.