Segfault with cfunction, possibly world age related

Full issue description here, along with workarounds and alternative code.

Following segfaults for me, tested on Windows, Linux, Julia 1.4.1 and 1.4.2:

module Foo
null_handler(x) = nothing
mutable struct A1{T}
    value::T
    h::Base.CFunction
    function A1(value::T) where {T}
        new{T}(value, @cfunction $(null_handler) Nothing (T,))
    end
end
function Base.setindex!(a::A1{T}, x::T) where {T}
    a.value = x
    ccall(Base.unsafe_convert(Ptr{Cvoid}, a.h), Nothing, (T,), x)
end
bar(a, x) = a[] = x
barl(a, x) = Base.invokelatest(setindex!, a, x)
end
a = Foo.A1(0)
Foo.bar(a, 1)

Outputs:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x668b7fa0 -- jl_typemap_entry_assoc_exact at /cygdrive/d/buildbot/worker/package_win64/build/src\typemap.c:775
in expression starting at REPL[3]:1
jl_typemap_entry_assoc_exact at /cygdrive/d/buildbot/worker/package_win64/build/src\typemap.c:775
jl_typemap_assoc_exact at /cygdrive/d/buildbot/worker/package_win64/build/src\julia_internal.h:1021 [inlined]
jl_lookup_generic_ at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2269
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2318
unknown function (ip: 000000002CEA65E8)
setindex! at .\REPL[1]:13 [inlined]
bar at .\REPL[1]:26
unknown function (ip: 000000002CEAA621)
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1700 [inlined]
do_call at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:369
eval_value at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:458
eval_stmt_value at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:409 [inlined]
eval_body at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:799
jl_interpret_toplevel_thunk at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:911
jl_toplevel_eval_flex at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:814
jl_toplevel_eval_flex at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:764
jl_toplevel_eval at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:823 [inlined]
jl_toplevel_eval_in at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:843
eval at .\boot.jl:331
eval_user_input at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\REPL\src\REPL.jl:86
macro expansion at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\REPL\src\REPL.jl:118 [inlined]
#26 at .\task.jl:358
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1700 [inlined]
start_task at /cygdrive/d/buildbot/worker/package_win64/build/src\task.c:687
Allocations: 853525 (Pool: 853350; Big: 175); GC: 1

Not sure why Keno wasn’t able to reproduce and closed the ticket, but anyone else able to run this and verify, or have any ideas why it’s crashing?

I noticed calling it through Base.invokelatest(), as seen in barl() resolves the problem. That’s not a useful workaround in this case, but made me wonder if it’s a world age issue of some sort.

I can reproduce in Julia 1.4.1, but it seems to be resolved in 1.5.0-rc1

Also segfaults for me

julia> versioninfo()
Julia Version 1.4.2
Commit 44fa15b150* (2020-05-23 18:35 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Pentium(R) 3558U @ 1.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, haswell)
Environment:
  JULIA_DIR = /home/myuser/.julia
1 Like
julia> module Foo
       null_handler(x) = nothing
       mutable struct A1{T}
           value::T
           h::Base.CFunction
           function A1(value::T) where {T}
               new{T}(value, @cfunction $(null_handler) Nothing (T,))
           end
       end
       function Base.setindex!(a::A1{T}, x::T) where {T}
           a.value = x
           ccall(Base.unsafe_convert(Ptr{Cvoid}, a.h), Nothing, (T,), x)
       end
       bar(a, x) = a[] = x
       barl(a, x) = Base.invokelatest(setindex!, a, x)
       end
Main.Foo


julia> a = Foo.A1(0)
Main.Foo.A1{Int64}(0, Base.CFunction(Ptr{Nothing} @0x000000002d6238e0, Main.Foo.null_handler, Ptr{Nothing} @0x0000000000000000, Ptr{Nothing} @0x0000000000000000))

julia> Foo.bar(a, 1)
1

julia> versioninfo()
Julia Version 1.5.0-rc1.0
Commit 24f033c951 (2020-06-26 20:13 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: AMD Ryzen 5 3600 6-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, znver1)

julia>

That’s great to know. Wonder if it’s a fix that can be back ported.