Segfault compiling code using PyCall


#1

Hi folks,

I’m trying to get a compiled binary out of Julia 1.1 for a program that makes use of PyCall, but Julia is segfaulting during the compilation. Any recommendations how I might go about debugging this? Are there any known limitations with PyCall an AoT compilation? I see this even with a very trivial example (see below). Thanks,

Dara

bash# /test/julia-1.1.0/bin/julia -Cnative -J/test/julia-1.1.0/lib/julia/sys.so --compile=yes --depwarn=no --startup-file=no --compiled-modules=no -g1 --output-o hello.a -e 'Base.__init__(); Sys.__init__() # initialize \`Base\` and \`Sys\` modules
pushfirst!(Base.DEPOT_PATH, "cache_ji_v1.1.0") # save precompiled modules locally
include("/tmp/hello.jl") # include Julia program file
signal (11): Segmentation fault
in expression starting at /tmp/hello.jl:3
PyUnicode_InternInPlace at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0 (unknown line)
PyUnicode_InternFromString at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0 (unknown line)
PyImport_Import at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0 (unknown line)
PyImport_ImportModule at /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0 (unknown line)
_pyimport at /julia-1.1.0/pkg/packages/PyCall/0jMpb/src/PyCall.jl:411
pyimport at /julia-1.1.0/pkg/packages/PyCall/0jMpb/src/PyCall.jl:435
jl_fptr_trampoline at /buildworker/worker/package_linux64/build/src/gf.c:1864
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2219
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:323
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:411
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:362 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:773
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:885
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f31073eff2f)
unknown function (ip: 0x3)
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:894
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:764
jl_eval_module_expr at /buildworker/worker/package_linux64/build/src/toplevel.c:179
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:614
jl_parse_eval_all at /buildworker/worker/package_linux64/build/src/ast.c:883
jl_load at /buildworker/worker/package_linux64/build/src/toplevel.c:826
include at ./boot.jl:326 [inlined]
include_relative at ./loading.jl:1038
...
bash# cat /tmp/hello.jl 
module Hello
using PyCall
@pyimport math

Base.@ccallable function julia_main(ARGS::Vector{String})::Cint
    x = math.sin(math.pi / 4) - sin(pi / 4)
    println("hello, world $(x)")
    return 0
end

end

#3

Doing @pyimport at top level inside a compiled (or even simply precompiled) module is not safe because the resulting python objects aren’t valid when the module is loaded again. There’s more information about this here: https://github.com/JuliaPy/PyCall.jl/blob/master/README.md#using-pycall-from-julia-modules