JuliaDebug / Cthulhu.jl

The slow descent into madness
MIT License
657 stars 41 forks source link

`UndefVarError`: `mi` not defined #333

Closed jishnub closed 1 year ago

jishnub commented 1 year ago

https://github.com/JuliaDebug/Cthulhu.jl/blob/a870c8aa153f6cb69d1e5e17784b43e4f7f67e25/src/Cthulhu.jl#L476-L483

In line 476, mi is not defined. In fact, it seems to be initialized on line 483

jishnub commented 1 year ago

As an example of where this is hit in real code (just press enter and select the only option a couple of times):

julia> using ApproxFun, Cthulhu

julia> @descend_code_warntype Fun(Fun(Legendre()), NormalizedLegendre())
Fun(f::Fun, d::Space) @ ApproxFunBase ~/.julia/packages/ApproxFunBase/QF2Vw/src/constructors.jl:78
Body::Fun{NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}}
78 1 ── %1  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    │╻╷  coefficients
   │    %2  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    ││╻╷  ncoefficients
   │    %3  = Base.arraylen(%2)::Int64                                                                                                                            │││╻   length
   │    %4  = (%3 === 0)::Bool                                                                                                                                    ││╻   ==
   └───       goto #3 if not %4                                                                                                                                   ││  
   2 ──       goto #9                                                                                                                                             ││  
   3 ── %7  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    │││╻   getproperty
   │    %8  = Base.arraylen(%7)::Int64                                                                                                                            │││╻   length
   │    %9  = (%8 === 1)::Bool                                                                                                                                    ││╻   ==
   └───       goto #5 if not %9                                                                                                                                   ││  
   4 ── %11 = Base.arrayref(true, %1, 1)::Float64                                                                                                                 ││╻   getindex
   │    %12 = Base.eq_float(%11, 0.0)::Bool                                                                                                                       │││╻   ==
   │    %13 = Base.and_int(%12, true)::Bool                                                                                                                       │││╻   &
   │    %14 = Base.and_int(%13, true)::Bool                                                                                                                       ││││
   └───       goto #6                                                                                                                                             ││  
   5 ──       nothing                                                                                                                                             │   
   6 ┄─ %17 = φ (#4 => %14, #5 => false)::Bool                                                                                                                    ││  
   └───       goto #8 if not %17                                                                                                                                  ││  
   7 ──       goto #9                                                                                                                                             ││  
   8 ── %20 = Base.getfield(f, :space)::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}                                                                        ││╻╷  space
   │    %21 = invoke ApproxFunBase.defaultcoefficients(%1::Vector{Float64}, %20::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}, d::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::Vector{Float64}
   └───       goto #10                                                                                                                                            ││  
   9 ┄─       goto #10                                                                                                                                            ││  
   10 ┄ %24 = φ (#8 => %21, #9 => %1)::Vector{Float64}                                                                                                            │   
   11 ─ %25 = %new(Fun{NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}}, d, %24)::Fun{NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}}
   └───       goto #12                                                                                                                                            │││ 
   12 ─       goto #13                                                                                                                                            ││  
   13 ─       return %25                                                                                                                                          │   
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [h]ide type-stable statements, [d]ebuginfo, [r]emarks, [e]ffects, [i]nlining costs, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
 • %21 = invoke defaultcoefficients(::Vector{Float64},::Jacobi{ChebyshevInterval{Float64}, Float64, Int64},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::…
   ↩
defaultcoefficients(f, a, b) @ ApproxFunBase ~/.julia/packages/ApproxFunBase/QF2Vw/src/Space.jl:371
Body::Vector{Float64}
372 1 ─ %1 = invoke #self#(f::Vector{Float64}, a::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}, b::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, $(QuoteNode(Val{false}()))::Val{false})::Vector{Float64}
    └──      return %1                                                                                                                                                              │
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [h]ide type-stable statements, [d]ebuginfo, [r]emarks, [e]ffects, [i]nlining costs, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
 • %1 = invoke defaultcoefficients(::Vector{Float64},::Jacobi{ChebyshevInterval{Float64}, Float64, Int64},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64},::Val{false})
   ↩
┌ Info: Inference discarded the source for this call because of recursion:
└ Cthulhu nevertheless is trying to retrieve the source for further inspection.
ERROR: UndefVarError: `mi` not defined
Stacktrace:
  [1] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Cthulhu.DInfo.DebugInfo, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:476
  [2] kwcall(::NamedTuple{(:override, :debuginfo, :optimize, :interruptexc, :iswarn, :hide_type_stable, :remarks, :with_effects, :inline_cost, :type_annotations), Tuple{Nothing, Cthulhu.DInfo.DebugInfo, Vararg{Bool, 8}}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:408
  [3] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Cthulhu.DInfo.DebugInfo, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:600
  [4] kwcall(::NamedTuple{(:override, :debuginfo, :optimize, :interruptexc, :iswarn, :hide_type_stable, :remarks, :with_effects, :inline_cost, :type_annotations), Tuple{Nothing, Cthulhu.DInfo.DebugInfo, Vararg{Bool, 8}}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:408
  [5] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Symbol, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:600
  [6] #_descend#97
    @ ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:731 [inlined]
  [7] #_descend#100
    @ ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:747 [inlined]
  [8] kwcall(::NamedTuple{(:iswarn,), Tuple{Bool}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, args::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:744
  [9] __descend_with_error_handling(args::Any; terminal::Any, kwargs::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:234
 [10] kwcall(::Any, ::typeof(Cthulhu.__descend_with_error_handling), args::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:231
 [11] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:iswarn,), Tuple{Bool}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:223
 [12] kwcall(::NamedTuple{(:iswarn,), Tuple{Bool}}, ::typeof(Cthulhu._descend_with_error_handling), f::Any, argtypes::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:215
 [13] descend_code_warntype(::Any, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:199
 [14] descend_code_warntype(::Any, ::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:199
 [15] top-level scope
    @ REPL[85]:1

julia> @descend Fun(Fun(Legendre()), NormalizedLegendre())
Fun(f::Fun, d::Space) @ ApproxFunBase ~/.julia/packages/ApproxFunBase/QF2Vw/src/constructors.jl:78
   ∘ ── %0 = invoke Fun(::Fun{Jacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::…
78 1 ── %1  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    │╻╷  coefficients
   │    %2  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    ││╻╷  ncoefficients
   │    %3  = Base.arraylen(%2)::Int64                                                                                                                            │││╻   length
   │    %4  = (%3 === 0)::Bool                                                                                                                                    ││╻   ==
   └───       goto #3 if not %4                                                                                                                                   ││  
   2 ──       goto #9                                                                                                                                             ││  
   3 ── %7  = Base.getfield(f, :coefficients)::Vector{Float64}                                                                                                    │││╻   getproperty
   │    %8  = Base.arraylen(%7)::Int64                                                                                                                            │││╻   length
   │    %9  = (%8 === 1)::Bool                                                                                                                                    ││╻   ==
   └───       goto #5 if not %9                                                                                                                                   ││  
   4 ── %11 = Base.arrayref(true, %1, 1)::Float64                                                                                                                 ││╻   getindex
   │    %12 = Base.eq_float(%11, 0.0)::Bool                                                                                                                       │││╻   ==
   │    %13 = Base.and_int(%12, true)::Bool                                                                                                                       │││╻   &
   │    %14 = Base.and_int(%13, true)::Bool                                                                                                                       ││││
   └───       goto #6                                                                                                                                             ││  
   5 ──       nothing::Nothing                                                                                                                                    │   
   6 ┄─ %17 = φ (#4 => %14, #5 => false)::Bool                                                                                                                    ││  
   └───       goto #8 if not %17                                                                                                                                  ││  
   7 ──       goto #9                                                                                                                                             ││  
   8 ── %20 = Base.getfield(f, :space)::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}                                                                        ││╻╷  space
   │    %21 = invoke ApproxFunBase.defaultcoefficients(%1::Vector{Float64}, %20::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}, d::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::Vector{Float64}
   └───       goto #10                                                                                                                                            ││  
   9 ┄─       goto #10                                                                                                                                            ││  
   10 ┄ %24 = φ (#8 => %21, #9 => %1)::Vector{Float64}                                                                                                            │   
   11 ─ %25 = %new(Fun{NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}}, d, %24)::Fun{NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, Float64, Vector{Float64}}
   └───       goto #12                                                                                                                                            │││ 
   12 ─       goto #13                                                                                                                                            ││  
   13 ─       return %25                                                                                                                                          │   
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [h]ide type-stable statements, [d]ebuginfo, [r]emarks, [e]ffects, [i]nlining costs, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
 • %21 = invoke defaultcoefficients(::Vector{Float64},::Jacobi{ChebyshevInterval{Float64}, Float64, Int64},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::…
   ↩
defaultcoefficients(f, a, b) @ ApproxFunBase ~/.julia/packages/ApproxFunBase/QF2Vw/src/Space.jl:371
    ∘ ─ %0 = invoke defaultcoefficients(::Vector{Float64},::Jacobi{ChebyshevInterval{Float64}, Float64, Int64},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64})::…    
372 1 ─ %1 = invoke #self#(f::Vector{Float64}, a::Jacobi{ChebyshevInterval{Float64}, Float64, Int64}, b::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64}, $(QuoteNode(Val{false}()))::Val{false})::Vector{Float64}
    └──      return %1                                                                                                                                                              │
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [h]ide type-stable statements, [d]ebuginfo, [r]emarks, [e]ffects, [i]nlining costs, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
 • %1 = invoke defaultcoefficients(::Vector{Float64},::Jacobi{ChebyshevInterval{Float64}, Float64, Int64},::NormalizedJacobi{ChebyshevInterval{Float64}, Float64, Int64},::Val{false})
   ↩
┌ Info: Inference discarded the source for this call because of recursion:
└ Cthulhu nevertheless is trying to retrieve the source for further inspection.
ERROR: UndefVarError: `mi` not defined
Stacktrace:
  [1] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Cthulhu.DInfo.DebugInfo, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:476
  [2] kwcall(::NamedTuple{(:override, :debuginfo, :optimize, :interruptexc, :iswarn, :hide_type_stable, :remarks, :with_effects, :inline_cost, :type_annotations), Tuple{Nothing, Cthulhu.DInfo.DebugInfo, Vararg{Bool, 8}}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:408
  [3] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Cthulhu.DInfo.DebugInfo, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:600
  [4] kwcall(::NamedTuple{(:override, :debuginfo, :optimize, :interruptexc, :iswarn, :hide_type_stable, :remarks, :with_effects, :inline_cost, :type_annotations), Tuple{Nothing, Cthulhu.DInfo.DebugInfo, Vararg{Bool, 8}}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:408
  [5] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, curs::Cthulhu.CthulhuCursor; override::Nothing, debuginfo::Symbol, optimize::Bool, interruptexc::Bool, iswarn::Bool, hide_type_stable::Bool, verbose::Nothing, remarks::Bool, with_effects::Bool, inline_cost::Bool, type_annotations::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:600
  [6] #_descend#97
    @ ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:731 [inlined]
  [7] #_descend#100
    @ ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:747 [inlined]
  [8] kwcall(::NamedTuple{(:iswarn,), Tuple{Bool}}, ::typeof(Cthulhu._descend), term::REPL.Terminals.TTYTerminal, args::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:744
  [9] __descend_with_error_handling(args::Any; terminal::Any, kwargs::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:234
 [10] kwcall(::Any, ::typeof(Cthulhu.__descend_with_error_handling), args::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:231
 [11] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:iswarn,), Tuple{Bool}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:223
 [12] kwcall(::NamedTuple{(:iswarn,), Tuple{Bool}}, ::typeof(Cthulhu._descend_with_error_handling), f::Any, argtypes::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:215
 [13] descend_code_typed(::Any, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:168
 [14] descend_code_typed(::Any, ::Any)
    @ Cthulhu ~/.julia/packages/Cthulhu/eS0ye/src/Cthulhu.jl:168
 [15] top-level scope
    @ REPL[86]:1
jishnub commented 1 year ago

This seems to be fixable by changing line 476 to additional_descend(get_mi(curs)), as suggested by Tim Holy on discourse

vtjnash commented 1 year ago

I just hit this also. There is an @goto show_menu that seems to be jumping over the initialization code for the loop.