Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gc: Do not finish lazy sweeps when freeing the object space #24

Merged
merged 1 commit into from Jan 29, 2015

Commits on Jan 23, 2015

  1. gc: Do not finish lazy sweeps when freeing the object space

    When freeing the object space from `ruby_vm_destruct`, we were
    performing a `gc_rest_sweep` to wrap up any potentially undergoing lazy
    sweeps.
    
    This operation is extremely dangerous because it is performed without
    a GVL (which has been removed previously in `ruby_vm_destruct`) and
    without a main thread to operate with (which has been cleared previously
    when freeing the main VM thread in `ruby_vm_destruct`). Since finishing
    a lazy sweep on the heap can cause objects to be deallocated, if the
    free function of any of these objects uses threading information, it
    will segfault.
    
    The builtin `Fiber` object (cont.c), for instance, accesses current
    thread information with `GET_THREAD()` when being freed, and can
    potentially segfault.  Any user defined T_DATA with a free callback
    can also trigger segfaults, and likewise for any object in Rubyland
    with a finalizer.
    
    Because of the way that the MRI teardown process functions, the only way
    that a lazy sweep can be underway when freeing the object space is if it
    was triggered when calling the on-exit finalizers
    (`rb_gc_call_finalizer_at_exit`). Before calling all the object
    finalizers, `rb_objspace_call_finalizer` finishes any current lazy
    sweeps. However, since the process of calling finalizers can allocate
    more objects on the Ruby heap, it is possible for a call to `newobj` to
    start another lazy sweep phase.
    
    Hence, instead of finishing the lazy sweep when freeing the object
    space, we attempt to finish it right after all the finalizers have been
    called. This way, we can assert that no lazy sweeps and no object
    deallocation will be performed after the main thread and the GVL have
    been cleared.
    vmg committed Jan 23, 2015
You can’t perform that action at this time.