Skip to content

Concurrency bug for disabling collection #278

Open

Description

@qinsoon

Mostly mmtk/mmtk-core#1398. The API is_collection_enabled is not thread safe, and there is no way to implement it in a thread safe way in the binding side. The issue is that the check of is_collection_enabled and the update for the GC triggered state cannot happen atomically, so there can be a situation that MMTk checks is_collection_enabled, thinks it is okay to trigger a GC, but when MMTk actually triggers the GC, is_collection_enabled is flipped at the binding side.

We haven't confirmed any bug from this. I think we could just add an assertion in the binding side to make sure that GC is always disabled when we actually stops for a GC.

One potential solution to the bug is to introduce thread-safe GC enabling APIs to MMTk core, and use that API for Julia. Though Julia currently has jl_gc_enable and jl_gc_is_enabled in the interface, it still bypasses the API and checks/sets jl_gc_disable_counter and ptls->disable_gc, specifically in the following places:

  • Julia has a global state jl_gc_disable_counter and a thread local state disable_gc. It seem the runtime code mixes the use of both.
  • Julia runtime may directly set jl_gc_disable_counter without using jl_gc_enable, such as in jl_adopt_thread in threading.c [1], and jl_exit_thread0_cb in signals-unix.c [2].
  • Julia runtime may directly set pltls->disable_gc without using jl_gc_enable, such as in jl_init_threadtls in threading.c [3].

[1] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L434
[2] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L555 and https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L1089
[3] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L349

Activity

  1. NHDaly commented on Feb 20, 2026

    @NHDaly
    Contributor

    I hit this today while precompiling julia in 1.12 on the moving branch:

    ERROR: The following 1 dependency failed to precompile:
    
    MozillaCACerts_jll
    
    Failed to precompile MozillaCACerts_jll [14a3606d-f60d-562e-9121-12d972cd8159] to "/tmp/nix-build-julia-mmtk.drv-0/source/usr/share/julia/compiled/v1.12/MozillaCACerts_jll/jl_OMtp4C".
    ERROR: An MMTk GC thread panicked.  This is a bug.
    panicked at src/collection.rs:62:9:
    Collection is disabled when threads are stopped for a GC. This is a concurrency bug, see https://github.com/mmtk/mmtk-julia/issues/278.
    Backtrace is disabled.
    run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    So it is indeed possible to happen in real life.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions