Skip to content

Meta-Issue: Mutli-threading leads to segfaults #1096

Closed

Description

@axsk

This seems to be coming up quite often, in order to track this issue I took the liberty to create this meta-issue linking all other related issues I could find:

#1095
#1090
#1088
#1083
#1078
#1077
#1072

Affected repos:
timholy/Revise.jl#989

Possible also related (crashes/segfaults)
#1082
#1080

Activity

  1. axsk commented on Jan 22, 2026

    @axsk
    Author

    Seeing that the last change to this repo is older then two years, is it correct to assume it has become unmaintained and no fix is to be expected?

  2. topolarity commented on Mar 10, 2026

    @topolarity
    Contributor

    Reproducer:

    using Base.Threads
    using PyCall
    o = PyObject(randn(3,3))
    t = Threads.@spawn begin
        println(Core.stderr, propertynames(o))
    end
    wait(t)
    $ julia +1.12 --project=. mwe.jl
    
    [119772] signal 11 (1): Segmentation fault
    in expression starting at /home/topolarity/repos/claude/PyCall.jl/mwe.jl:7
    _PyType_Lookup at /usr/lib/x86_64-linux-gnu/libpython3.12.so.1.0 (unknown line)
    _PyObject_LookupSpecial at /usr/lib/x86_64-linux-gnu/libpython3.12.so.1.0 (unknown line)
    PyObject_Dir at /usr/lib/x86_64-linux-gnu/libpython3.12.so.1.0 (unknown line)

    The issue seems to be that PyCall.jl does not manage thread states or the GIL: https://docs.python.org/3/c-api/threads.html

    Here's a "fixed" version of the example:

    using Base.Threads
    using PyCall
    ccall(:PyEval_InitThreads, Cvoid, ()) # enable threads / GIL
    o = PyObject(randn(3,3))
    tstate = ccall(:PyEval_SaveThread, Ptr{Cvoid}, ()) # Release GIL
    
    t = Threads.@spawn begin
        GIL = ccall(:PyGILState_Ensure, Ptr{Cvoid}, ())
        println(Core.stderr, propertynames(o))
        ccall(:PyGILState_Release, Cvoid, (Ptr{Cvoid},), GIL)
    end
    wait(t)
    
    ccall(:PyEval_RestoreThread, Cvoid, (Ptr{Cvoid},), tstate) # Re-acquire GIL
  3. topolarity commented on Mar 10, 2026

    @topolarity
    Contributor

    Equivalent fix in PythonCall.jl: JuliaPy/PythonCall.jl#677

    Looks like they opt to leave the GIL-management to users for most of the API. For propertynames (which is called by the REPL tab-complete), they provide a mechanism to request execution on the main thread.

  4. yuyichao commented on Oct 2, 2026

    @yuyichao
    Collaborator

    This is now causing significant problem whenever I want to use PyPlot on a new computer. There doesn't seem to be any alternative proposed here other than #1097. Given that it is relatively low impact on the user API (I've used the rebased version for a new months now) I'd like to just merge it soon. If there's a better approach we can switch the implementation later. I don't think this would cause any more of an API breakage since even if the new/final approach require changes in the user code, those code are already broken as of now and people have already been assuming that it works.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions