Closed azreika closed 1 year ago
@MikeInnes noted that getting rid of the return
in foo
fixes the problem. This is fine on both master and Julia 1.8.2:
function foo(::Type{T1}, value::T2) where {T1<:Tuple,T2<:Tuple}
v = Ref(value)
GC.@preserve v begin
ptr = pointer_from_objref(v)
Base.unsafe_load(reinterpret(Ptr{T1}, ptr))
end
end
struct MyString
str::String
b::Bool
end
foo(Tuple{MyString}, (MyString("A", false),))
julia> foo(Tuple{MyString}, (MyString("A", false),))
(MyString("A", false),)
unsafe_load of a Bool is probably undefined (it is only defined for C-compatible types), so this is probably not fixable
If the Bool
is replaced by Int32
the issue remains. It does work with Int64
, but only because the Ref is then heap allocated. I don't know if the bug is only present for stack-allocated Refs or if it only triggers reliably there.
Specifically, the issue is not that unsafe_load
fails (as you might expect) but that it mangles the String
pointer (while seemingly preserving the value of the bool/int field).
The use of return
prevents the gc_preserve_end
expression from making it into the code_typed
, which seems like it could be the root of the issue. (But I don't know if the compiler is supposed to handle this case, eg by inferring the preserve_end
when the IR contains preserve_begin
.)
Looking at the LLVM IR, the failing example will alloca
the ref and then memcpy
from the struct pointer; when the return
statement is present the first memcpy
is followed by an @llvm.lifetime.end
for the stack-allocated ref. That goes away when return
is removed.
Another oddity: Julia will memcpy
the ref pointer to an output pointer to store the result of unsafe_load
, then again memcpy
that to an output pointer, AFAICT. However, with the return
present the input to the final memcpy
is the pointer for the original ref, not for the output of unsafe_load
as you'd expect; so that output is allocated and memcpy
d redundantly. This affects both the heap- and stack-allocated Ref cases.
Hello , I am willing to contribute to the issue So please assign me to this Issue , I want to know some resources which I can use to solve this Issue . Thanks for your time
The return seems to trigger the segfault because of printing, which I imagine happens because we are observing something bad.
@vtjnash is it legal to return from a GC.preserve
block?
foo(Tuple{MyString}, (MyString("A", Int32(1)),))
(MyString(
[64706] signal (11.2): Segmentation fault: 11
in expression starting at none:0
sig_match_simple at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
jl_typemap_entry_assoc_exact at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
_show_default at ./show.jl:476
show_default at ./show.jl:459 [inlined]
show at ./show.jl:454 [inlined]
show_delim_array at ./show.jl:1325
show_delim_array at ./show.jl:1310 [inlined]
show at ./show.jl:1343 [inlined]
show at ./multimedia.jl:47
unknown function (ip: 0x1089b4047)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
#55 at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:273
jfptr_YY.55_60608 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
with_repl_linfo at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:551
display at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:261 [inlined]
display at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:278 [inlined]
display at ./multimedia.jl:340
jfptr_display_40886 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
jl_f__call_latest at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
print_response at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:0
#57 at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:284
jfptr_YY.57_59645 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
with_repl_linfo at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:551
print_response at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:282
do_respond at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:893
jfptr_do_respond_60526 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
jl_f__call_latest at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
#invokelatest#2 at ./essentials.jl:816 [inlined]
invokelatest at ./essentials.jl:813 [inlined]
run_interface at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/LineEdit.jl:2644
jfptr_run_interface_59491 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
run_frontend at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-macmini-aarch64-2.0/build/default-macmini-aarch64-2-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/REPL/src/REPL.jl:1293
#62 at ./task.jl:514
jfptr_YY.62_60256 at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
ijl_apply_generic at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
start_task at /Users/gabrielbaraldi/.julia/juliaup/julia-1.9.0-beta3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.9.dylib (unknown line)
Allocations: 2990 (Pool: 2979; Big: 11); GC: 0
It is legal, though the alloc-opt pass might be unaware of that as it is seen to insert an llvm.lifetime.end after the last semantic use (the pointer_from_objref call)
@lucifer1702 you can try this, but this is probably a really bad issue for a first PR. It involves a lot of really low level stuff.
@oscardssmith thanks for the advice . I will look for other issues to contribute . I am particularly interested in the field of Graph neural networks and computer vision . Is there any repo which is active that I can contribute to ?. Thanks
You might get better advice on slack/discourse, but there's always stuff to do in the Flux and various autodiff packages
Thanks for the suggestion
Thanks for the fix! ❤️
For the given script:
On master, we get a weird result on the first call to
foo
, and a segfault when the call is repeated:Version info:
Running on Julia 1.8.2 we consistently get a segfault on the first call:
Version info: