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

Crash (core-dump) in Julia 0.7.0 #29175

Closed
mabokhamis opened this issue Sep 13, 2018 · 5 comments
Closed

Crash (core-dump) in Julia 0.7.0 #29175

mabokhamis opened this issue Sep 13, 2018 · 5 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior compiler:lowering Syntax lowering (compiler front end, 2nd stage)

Comments

@mabokhamis
Copy link

The following code snippet causes Julia 0.7.0 to crash:

function get_tuple_prefix(tuple::T) where {T <: Tuple}
    prefix::Tuple{T.parameters[1:end-1]...} = tuple[1:length(T.parameters)-1]
    return prefix
end

println(get_tuple_prefix((1, 1, 1)))

Version info:

Julia Version 0.7.0
Commit a4cb80f3ed (2018-08-08 06:46 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, skylake)

The error report is:

Unreachable reached at 0x7f2ba5f00340

signal (4): Illegal instruction
in expression starting at /home/mahmoud/Repositories/raicode/src/QueryEvaluator/playground3.jl:6
get_tuple_prefix at /home/mahmoud/Repositories/raicode/src/QueryEvaluator/playground3.jl:2
unknown function (ip: 0x7f2ba5f003b1)
jl_fptr_trampoline at /buildworker/worker/package_linux64/build/src/gf.c:1829
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2182
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:324
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:428
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:363 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:686
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:799
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f2bb761b1bf)
unknown function (ip: (nil))
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:808
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:831
jl_parse_eval_all at /buildworker/worker/package_linux64/build/src/ast.c:841
jl_load at /buildworker/worker/package_linux64/build/src/toplevel.c:865
include at ./boot.jl:317 [inlined]
include_relative at ./loading.jl:1038
include at ./sysimg.jl:29
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2182
include at ./client.jl:398
jl_fptr_trampoline at /buildworker/worker/package_linux64/build/src/gf.c:1829
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2182
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:324
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:428
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:363 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:686
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:799
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f2bb761864f)
unknown function (ip: 0xffffffffffffffff)
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:808
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:831
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/builtins.c:633
eval at ./boot.jl:319
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2182
eval_user_input at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl:85
macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl:117 [inlined]
#28 at ./task.jl:262
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2182
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1538 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:268
unknown function (ip: 0xffffffffffffffff)
Allocations: 145764 (Pool: 145684; Big: 80); GC: 0
Illegal instruction (core dumped)
@chethega
Copy link
Contributor

Can reproduce crash 1.0.0, and OOB error on master. Looks like an inference problem? But @code_llvm and @code_native actually produce some code instead of crashing, so it's unclear to me.

julia> @code_lowered get_tuple_prefix((1, 1, 1));
julia> @code_typed get_tuple_prefix((1, 1, 1));
ERROR: BoundsError: attempt to access 0-element Array{Core.Compiler.NewNode,1} at index [6]
Stacktrace:
 [1] typeinf_code(::Method, ::Any, ::Core.SimpleVector, ::Bool, ::Core.Compiler.Params) at ./compiler/typeinfer.jl:515
 [2] #code_typed#18(::Bool, ::Function, ::Any, ::Any) at ./reflection.jl:882
 [3] code_typed(::Any, ::Any) at ./reflection.jl:872
 [4] top-level scope at /build/julia/src/julia/usr/share/julia/stdlib/v1.0/InteractiveUtils/src/macros.jl:110

@JeffBezanson JeffBezanson added bug Indicates an unexpected problem or unintended behavior compiler:lowering Syntax lowering (compiler front end, 2nd stage) labels Sep 14, 2018
@JeffBezanson JeffBezanson self-assigned this Sep 14, 2018
@JeffBezanson
Copy link
Member

Lowering seems to be referencing the wrong ssavalue for computing end inside the declared type:

julia> @code_lowered get_tuple_prefix((1, 1, 1))
CodeInfo(
2 1 ─ %1  = (Base.getproperty)($(Expr(:static_parameter, 1)), :parameters)                     │
  │   %2  = (Main.length)(%1)                                                                  │
  │   %3  = %2 - 1                                                                             │
  │   %4  = 1:%3                                                                               │
  │   %5  = (Base.getindex)(tuple, %4)                                                         │
  │   %6  = (Core.tuple)(Main.Tuple)                                                           │
  │         (Base.getproperty)($(Expr(:static_parameter, 1)), :parameters)                     │
  │   %8  = (Base.lastindex)(%15)                                                              │
  │   %9  = %8 - 1                                                                             │
  │   %10 = 1:%9                                                                               │
  │   %11 = (Base.getindex)(%15, %10)                                                          │
  │   %12 = (Core._apply)(Core.apply_type, %6, %11)                                            │
  │   %13 = (Base.convert)(%12, %5)                                                            │
  │   %14 = (Core.tuple)(Main.Tuple)                                                           │
  │   %15 = (Base.getproperty)($(Expr(:static_parameter, 1)), :parameters)                     │
  │   %16 = (Base.lastindex)(%15)                                                              │
  │   %17 = %16 - 1                                                                            │
  │   %18 = 1:%17                                                                              │
  │   %19 = (Base.getindex)(%15, %18)                                                          │
  │   %20 = (Core._apply)(Core.apply_type, %14, %19)                                           │
  │         prefix = (Core.typeassert)(%13, %20)                                               │
3 └──       return prefix                                                                      │
)

Note the not-dominated use of %15.

@JeffBezanson
Copy link
Member

In the meantime if you need an implementation of this, this should be much faster:

get_tuple_prefix(x::Tuple{Any}) = ()
tail(x, rest...) = rest
get_tuple_prefix(x::Tuple{Any,Vararg{Any}}) = (x[1], get_tuple_prefix(tail(x...))...)

@mabokhamis
Copy link
Author

In the meantime if you need an implementation of this, this should be much faster:

get_tuple_prefix(x::Tuple{Any}) = ()
tail(x, rest...) = rest
get_tuple_prefix(x::Tuple{Any,Vararg{Any}}) = (x[1], get_tuple_prefix(tail(x...))...)

Interesting that the above code is faster despite the recursion in the last line. If the input tuple x has a large length N, does the above code run in O(N) or O(N^2)? In other words, does the above code result in copying the whole previous tuple get_tuple_prefix(tail(x...)) every time a new x[1] is prepended to the tuple (which would result in O(N^2) time)?

@JeffBezanson
Copy link
Member

It will be fully unrolled for small tuples, but yes it will eventually become O(n^2). For long tuples ntuple(i->getfield(t,i), length(t)-1) will work better. Or for a bit more generality you can use a method like this:

@Base.pure function tuple_type_prefix(::Type{T}) where T<:Tuple
    return Tuple{T.parameters[1:end-1]...}
end

function get_tuple_prefix(tuple::T) where {T <: Tuple}
    prefix::tuple_type_prefix(T) = tuple[1:length(tuple)-1]
    return prefix
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior compiler:lowering Syntax lowering (compiler front end, 2nd stage)
Projects
None yet
Development

No branches or pull requests

3 participants