Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault with typo in iterate(x, n) #29532

Closed
dalum opened this issue Oct 5, 2018 · 3 comments
Closed

Segmentation fault with typo in iterate(x, n) #29532

dalum opened this issue Oct 5, 2018 · 3 comments

Comments

@dalum
Copy link
Contributor

dalum commented Oct 5, 2018

Note the typo in Base.iterate(a, n) = iterate(a.data) (missing n on the right hand side):

julia> struct MyType{N,T}
       data::NTuple{N,T}
       end

julia> Base.iterate(a::MyType) = iterate(a.data)

julia> Base.iterate(a::MyType, n) = iterate(a.data)

julia> Base.length(a::MyType) = length(a.data)

julia> a = MyType((0., 0.))
MyType{2,Float64}(^P(0.0, 0.0))

julia> b = MyType((1., 0.))
MyType{2,Float64}((1.0, 0.0))

julia> MyType(Tuple(x + y for (x,y) in zip(a, b)))

signal (11): Segmentation fault
in expression starting at no file:0
jl_gc_pool_alloc at /home/dalum/Projects/julia/src/gc.c:963
jl_gc_alloc_ at /home/dalum/Projects/julia/src/julia_internal.h:274 [inlined]
jl_gc_alloc at /home/dalum/Projects/julia/src/gc.c:2668
_new_array_ at /home/dalum/Projects/julia/src/array.c:100 [inlined]
_new_array at /home/dalum/Projects/julia/src/array.c:158 [inlined]
jl_alloc_array_1d at /home/dalum/Projects/julia/src/array.c:418
Type at ./boot.jl:394 [inlined]
Type at ./boot.jl:413 [inlined]
_reformat_bt at ./error.jl:61
jl_apply_generic at /home/dalum/Projects/julia/src/gf.c:2184
catch_backtrace at ./error.jl:91
eval_user_input at /home/dalum/Projects/julia/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:97
macro expansion at /home/dalum/Projects/julia/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:117 [inlined]
#28 at ./task.jl:259
jl_apply_generic at /home/dalum/Projects/julia/src/gf.c:2184
jl_apply at /home/dalum/Projects/julia/src/julia.h:1537 [inlined]
start_task at /home/dalum/Projects/julia/src/task.c:268
unknown function (ip: 0xffffffffffffffff)
Allocations: 919274 (Pool: 919020; Big: 254); GC: 1
fish:~/Projects/julia/julia” terminated by signal SIGSEGV (Address boundary error)
@martinholters
Copy link
Member

Simpler reproduction:

struct Foo end

Base.iterate(::Foo) = (0, 0)
Base.iterate(::Foo, n) = n < 1000000 ? (0, n+1) : nothing
Base.length(::Foo) = 10

collect(i for i in Foo())

collect(::Generator) assumes the iterator not to lie about its length. The @inbounds annotations here:

julia/base/array.jl

Lines 655 to 669 in 1968b23

while true
y = iterate(itr, st)
y === nothing && break
el, st = y
if el isa T || typeof(el) === T
@inbounds dest[i] = el::T
i += 1
else
R = promote_typejoin(T, typeof(el))
new = similar(dest, R)
copyto!(new,1, dest,1, i-1)
@inbounds new[i] = el
return collect_to!(new, itr, i+1, st)
end
end

assume the dest array to be large enough to hold all generated elements, but it is allocated based on the length. I guess we could just replace the while true with while i <= lastindex(dest)? Then we would just produce the first length elements, which seems ok.

@martinholters
Copy link
Member

Ref. #29458 which should hopefully be made to also fix this.

@KristofferC
Copy link
Member

Dup of #28763

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants