Julia: Unreachable reached (illegal instruction) in SimJulia on 1.3

Created on 24 Sep 2019  ยท  8Comments  ยท  Source: JuliaLang/julia

After some discussion in https://github.com/BenLauwens/SimJulia.jl/issues/63 it seems the following is a regression in 1.3. Running (where some of this code has been macroexpanded from ResumableFunctions):

using ResumableFunctions
using SimJulia

mutable struct var"##403" <: ResumableFunctions.FiniteStateMachineIterator{Any}
    _state::UInt8
    sim::Simulation
    a::Int64
    b::Int64
    function var"##403"(sim::Simulation; )::var"##403"
        fsmi = new()
        fsmi._state = 0x00
        fsmi.sim = sim
        fsmi
    end
end
function fibonnaci(sim::Simulation; )::var"##403"
    var"##403"(sim; )
end
function (_fsmi::var"##403")(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
    _fsmi._state == 0x00 && @goto(_STATE_0)
    _fsmi._state == 0x01 && @goto(_STATE_1)
    error("@resumable function has stopped!")
    @label _STATE_0
    _fsmi._state = 0xff
    _arg isa Exception && throw(_arg)
    _fsmi.a = 0
    _fsmi.b = 1
    while true
        println(_fsmi.a)
        _fsmi._state = 0x01
        return timeout(_fsmi.sim, 1)
        @label _STATE_1
        _fsmi._state = 0xff
        _arg isa Exception && throw(_arg)
        (_fsmi.a, _fsmi.b) = (_fsmi.b, _fsmi.a + _fsmi.b)
    end
end

sim = Simulation()
@process fibonnaci(sim)
run(sim, 10)

crashes with

0
Unreachable reached at 0x7f1ab3271abf

signal (4): Illegal instruction
in expression starting at /home/kc/Documents/JuliaTests/failing.jl:44
execute at /home/kc/.julia/packages/SimJulia/alkAr/src/processes.jl:32
#3 at /home/kc/.julia/packages/SimJulia/alkAr/src/base.jl:51
_jl_invoke at /home/kc/julia/src/gf.c:2136 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
step at /home/kc/.julia/packages/SimJulia/alkAr/src/simulations.jl:39
run at /home/kc/.julia/packages/SimJulia/alkAr/src/base.jl:91
run at /home/kc/.julia/packages/SimJulia/alkAr/src/events.jl:29
unknown function (ip: 0x7f1ab3270cf6)
_jl_invoke at /home/kc/julia/src/gf.c:2136 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
jl_apply at /home/kc/julia/src/julia.h:1631 [inlined]
do_call at /home/kc/julia/src/interpreter.c:328
eval_value at /home/kc/julia/src/interpreter.c:417
eval_stmt_value at /home/kc/julia/src/interpreter.c:368 [inlined]
eval_body at /home/kc/julia/src/interpreter.c:764
jl_interpret_toplevel_thunk_callback at /home/kc/julia/src/interpreter.c:888
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f1acf11458f)
unknown function (ip: 0xffffffffffffffff)
jl_interpret_toplevel_thunk at /home/kc/julia/src/interpreter.c:897
jl_toplevel_eval_flex at /home/kc/julia/src/toplevel.c:814
jl_parse_eval_all at /home/kc/julia/src/ast.c:873
jl_load at /home/kc/julia/src/toplevel.c:878
include at ./boot.jl:328 [inlined]
include_relative at ./loading.jl:1105
include at ./Base.jl:31
_jl_invoke at /home/kc/julia/src/gf.c:2130 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
exec_options at ./client.jl:295
_start at ./client.jl:468
jfptr__start_2083 at /home/kc/julia/usr/lib/julia/sys.so (unknown line)
_jl_invoke at /home/kc/julia/src/gf.c:2130 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2300
jl_apply at /home/kc/julia/ui/../src/julia.h:1631 [inlined]
true_main at /home/kc/julia/ui/repl.c:96
main at /home/kc/julia/ui/repl.c:217
__libc_start_main at /build/glibc-KRRWSm/glibc-2.29/csu/../csu/libc-start.c:308
_start at /home/kc/julia/julia (unknown line)
Allocations: 744501 (Pool: 744209; Big: 292); GC: 1
[1]    27250 illegal hardware instruction (core dumped)  ~/julia/julia failing.jl

Running the code through JuliaInterpreter works fine.

Also, just renaming the variable var"##403" to something else, (like MyTest) makes the code work:

diff working.jl failing.jl
< mutable struct MyTest <: ResumableFunctions.FiniteStateMachineIterator{Any}
---
> mutable struct var"##403" <: ResumableFunctions.FiniteStateMachineIterator{Any}
10c9
<     function MyTest(sim::Simulation; )::MyTest
---
>     function var"##403"(sim::Simulation; )::var"##403"
17,18c16,17
< function fibonnaci(sim::Simulation; )::MyTest
<     MyTest(sim; )
---
> function fibonnaci(sim::Simulation; )::var"##403"
>     var"##403"(sim; )
20c19
< function (_fsmi::MyTest)(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
---
> function (_fsmi::var"##403")(_arg::Any=nothing; )::Union{Any, Nothing, Bool}
โžœ  ~/julia/julia working.jl
0
1
1
2
3
5
8
13
21
34
bug priority regression

Most helpful comment

Is it possible to learn this power?

All 8 comments

cc @c42f in case the renaming of the var".." variable to fix the crash is not a red herring.

Reduced to:

module a
abstract type b{c} end
end
module d
using ..a
export g, @h
mutable struct g fsmi :: a.b
  function g(func )
    i = new()
    i.fsmi = func(env )
    execute(i, i)
  end
end
macro h(expr)
  esc(:(g($(expr.args...))))
end
function execute(f, i)
  try
    i.fsmi()
  catch end
end
end
using .d
struct var"##403" <: a.b{Any}
  function var"##403"(e)
    new()
  end
end
function fibonnaci(e)var"##403"(j)
end
function (::var"##403")()
end
@h fibonnaci()

Is it possible to learn this power?

I suspect Tim is doing https://discourse.julialang.org/t/ann-automatic-test-case-reduction/17700 ;)

Further reduction:

abstract type B end

mutable struct G
    f :: B
    function G(x)
        g = new()
        g.f = x
        g.f()
    end
end

n = Symbol("#1")  # Needs to start with `#` ??

@eval begin
    struct $n <: B
    end

    function (::$n)()
    end

    x = $n()
end

G(x)

Looks like maybe a failure in type inference which is somehow related to internally named types (?)

for n in [Symbol("#1"), :X]
@eval module A


abstract type B end

struct $n <: B
end

function (::$n)()
end

x = $n()

mutable struct G
    f :: B
    function G(x)
        g = new()
        g.f = x
        g.f()
    end
end

using InteractiveUtils

println("Code for $(typeof(x))")
show(@code_typed G(x))
println()


end
end

Produces:

Code for Main.A.var"#1"
CodeInfo(
1 โ”€ %1 = Main.A.G::Core.Compiler.Const(Main.A.G, false)
โ”‚   %2 = %new(%1)::Main.A.G
โ”‚        Base.setfield!(%2, :f, $(QuoteNode(Main.A.var"#1"())))::Main.A.var"#1"
โ”‚   %4 = Base.getfield(%2, :f)::Main.A.B
โ”‚        (%4)()::Union{}
โ””โ”€โ”€      $(Expr(:unreachable))::Union{}
) => Union{}

Code for Main.A.X
CodeInfo(
1 โ”€ %1  = Main.A.G::Core.Compiler.Const(Main.A.G, false)
โ”‚   %2  = %new(%1)::Main.A.G
โ”‚         Base.setfield!(%2, :f, $(QuoteNode(Main.A.X())))::Main.A.X
โ”‚   %4  = Base.getfield(%2, :f)::Main.A.B
โ”‚   %5  = (isa)(%4, Main.A.X)::Bool
โ””โ”€โ”€       goto #3 if not %5
2 โ”€       goto #4
3 โ”€ %8  = (%4)()::Core.Compiler.Const(nothing, false)
โ””โ”€โ”€       goto #4
4 โ”„ %10 = ฯ† (#2 => nothing, #3 => %8)::Core.Compiler.Const(nothing, false)
โ””โ”€โ”€       return %10
) => Nothing

yet both these should be exactly the same, given they have identical structure (other than the funny name for typeof(x))

@JeffBezanson, @vtjnash, perhaps one of you could look at this soonish? It's the last thing for 1.3-RC3 (and only known regression with 1.3).

Bisected to 99d2406c98a720e9f9e555109297b577232a01a4 cc @vtjnash

This block from that commit looks relevant:

https://github.com/JuliaLang/julia/blob/d0365753fb57f57bcea097c05de8c07aef706561/src/datatype.c#L490-L497

Was this page helpful?
0 / 5 - 0 ratings

Related issues

helgee picture helgee  ยท  3Comments

StefanKarpinski picture StefanKarpinski  ยท  3Comments

m-j-w picture m-j-w  ยท  3Comments

tkoolen picture tkoolen  ยท  3Comments

sbromberger picture sbromberger  ยท  3Comments