JuliaPy / PythonPlot.jl

Plotting for Julia based on matplotlib.pyplot
MIT License
76 stars 10 forks source link

Segfault when exiting a Julia v1.11.1 session with multiple threads #45

Closed sethaxen closed 1 day ago

sethaxen commented 3 days ago

If I launch a Julia v1.11.1 session with more than 1 thread and if PythonPlot at any point enters scope, then Julia segfaults when I call exit. Besides just being annoying, this seems to prevent dependents of PythonPlot from being registered, since the General registry's automated tests seem to use multiple threads. This does not happen on Julia v1.10.6.

After cloning the master branch to my machine and instantiating it, I execute the following commands:

sethaxen@pop-os:~/projects/PythonPlot.jl$ JULIA_NUM_THREADS=1 julia --project=. -e 'import PythonPlot'
sethaxen@pop-os:~/projects/PythonPlot.jl$ JULIA_NUM_THREADS=2 julia --project=. -e 'import PythonPlot'

[4176879] signal 11 (1): Segmentation fault
in expression starting at none:0
_PyInterpreterState_GET at /usr/local/src/conda/python-3.12.5/Include/internal/pycore_pystate.h:133 [inlined]
get_state at /usr/local/src/conda/python-3.12.5/Objects/obmalloc.c:866 [inlined]
_PyObject_Malloc at /usr/local/src/conda/python-3.12.5/Objects/obmalloc.c:1563 [inlined]
PyObject_Malloc at /usr/local/src/conda/python-3.12.5/Objects/obmalloc.c:801 [inlined]
PyUnicode_New at /usr/local/src/conda/python-3.12.5/Objects/unicodeobject.c:1251 [inlined]
unicode_decode_utf8 at /usr/local/src/conda/python-3.12.5/Objects/unicodeobject.c:4693
PyUnicode_DecodeUTF8 at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/C/pointers.jl:303 [inlined]
pystr_fromUTF8 at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:635
pystr_fromUTF8 at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:636 [inlined]
pystr at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:644 [inlined]
Py at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:139 [inlined]
macro expansion at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:131 [inlined]
pygetattr at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/builtins.jl:62
getproperty at /home/sethaxen/.julia/packages/PythonCall/Nr75f/src/Core/Py.jl:273 [inlined]
#9 at /home/sethaxen/projects/PythonPlot.jl/src/pygui.jl:198
#816 at ./asyncevent.jl:313
unknown function (ip: 0x7f033434d66f)
jl_apply at /cache/build/builder-demeter6-6/julialang/julia-master/src/julia.h:2157 [inlined]
start_task at /cache/build/builder-demeter6-6/julialang/julia-master/src/task.c:1202
Allocations: 4441223 (Pool: 4441002; Big: 221); GC: 5
Segmentation fault (core dumped)

Here's my environment info

julia> versioninfo()
Julia Version 1.11.1
Commit 8f5b7ca12ad (2024-10-16 10:53 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, tigerlake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_NUM_THREADS = 1

(PythonPlot) pkg> st
Project PythonPlot v1.0.5
Status `~/projects/PythonPlot.jl/Project.toml`
  [5ae59095] Colors v0.13.0
  [992eb4ea] CondaPkg v0.2.24
  [b964fa9f] LaTeXStrings v1.4.0
  [6099a3de] PythonCall v0.9.23
  [81def892] VersionParsing v1.3.0
  [6462fe0b] Sockets v1.11.0
  [8dfed614] Test v1.11.0
GMcArdle commented 2 days ago

I'm seeing the same problem with Julia 1.11.0 upon exit after plotting. Same errors as above but with the python path /usr/local/src/conda/python-3.11.0 I hope to see this fixed soon

sethaxen commented 2 days ago

@GMcArdle, can you verify that the fix in #46 also fixes the segfault you're seeing?

GMcArdle commented 2 days ago

Well, I'm only familiar with using the package manager to install registered packages so I'd have to do a bit of research on how to point it at a fork on github version instead (and how to unpick the changes when I want to revert). I'll have a go but can't promise how soon

sethaxen commented 2 days ago

You can easily install from that PR's GitHub branch into a temporary environment with the following command:

julia -e '
    using Pkg
    Pkg.activate(; temp=true)
    Pkg.add(PackageSpec(url="https://github.com/sethaxen/PythonPlot.jl", rev="fixsegfault"))
    using PythonPlot'

Note that the following should reproduce the segfault:

julia -e '
    using Pkg
    Pkg.activate(; temp=true)
    Pkg.add("PythonPlot")
    using PythonPlot'
GMcArdle commented 2 days ago

Thanks, but in my case I've been using pythonplot as a backend for Plots.jl. To test that do I have to make my own fork of Plots.jl and rebuild it to use a local clone of PythonPlot or would it detect the local version by default?