Unreachable reached when using Dict for kwargs

I am getting an unreachable reached crash, when I convert a result from NLsolve.jl back to my custum type after calling nlsolve with a Dict containing the keyword arguments. If I give the same keyword arguments to nlsolve explicitly, everything works as expected. Below is a MWE and the message that I get when Julia crashes. I am on Julia 1.6.1 and NLsolve 4.5.1. Am I doing something wrong here or should this not be happening?

using Tensors
using NLsolve

mutable struct Residuals{T}
    σ::SymmetricTensor{2,3,T,6}
    κ::T
    α::SymmetricTensor{2,3,T,6}
    μ::T
end

function frommandel!(r::Residuals{T}, v::Vector{T}) where T
    M=6
    r.σ = frommandel(SymmetricTensor{2,3}, view(v, 1:M))
    r.κ = v[M+1]
    r.α = frommandel(SymmetricTensor{2,3}, view(v, M+2:2M+1))
    r.μ = v[2M+2]
    return r
end

function foo_nocrash(cache)
    x = Residuals(ones(SymmetricTensor{2,3}), 1.0, ones(SymmetricTensor{2,3}), 1.0)
    res = nlsolve(cache, ones(14); method=:newton)
    frommandel!(x, res.zero)
end

function foo_crash(cache, options)
    x = Residuals(ones(SymmetricTensor{2,3}), 1.0, ones(SymmetricTensor{2,3}), 1.0)
    res = nlsolve(cache, ones(14); options...)
    frommandel!(x, res.zero)
end

A = rand(14, 14)
function f!(b, x)
    b[:] = A*x
end
cache = NLsolve.OnceDifferentiable(f!, rand(14), rand(14); autodiff=:forward)
options = Dict{Symbol, Any}(:method=>:newton)

# no problem if kwargs are given explicitely
foo_nocrash(cache)

# kwargs in Dict and call from function crashes
foo_crash(cache, options)

Unreachable reached at 00000000619b61a8

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ILLEGAL_INSTRUCTION at 0x619b61a8 -- foo_crash at C:\Users\auth\.julia\dev\MaterialModels\src\unreachable_reached.jl:31
in expression starting at C:\Users\auth\.julia\dev\MaterialModels\src\unreachable_reached.jl:45
foo_crash at C:\Users\auth\.julia\dev\MaterialModels\src\unreachable_reached.jl:31
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1703 [inlined]
do_call at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:115
eval_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:204
eval_stmt_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:155 [inlined]
eval_body at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:576
jl_interpret_toplevel_thunk at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:670
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:877
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:825
jl_toplevel_eval at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:886 [inlined]
jl_toplevel_eval_in at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:929
eval at .\boot.jl:360 [inlined]
include_string at .\loading.jl:1094
_include at .\loading.jl:1148
include at .\client.jl:444
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1703 [inlined]
do_call at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:115
eval_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:204
eval_stmt_value at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:155 [inlined]
eval_body at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:576
jl_interpret_toplevel_thunk at /cygdrive/c/buildbot/worker/package_win64/build/src\interpreter.c:670
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:877
jl_toplevel_eval_flex at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:825
jl_toplevel_eval at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:886 [inlined]
jl_toplevel_eval_in at /cygdrive/c/buildbot/worker/package_win64/build/src\toplevel.c:929
eval at .\boot.jl:360 [inlined]
eval_user_input at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:139
repl_backend_loop at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:200
start_repl_backend at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:185
#run_repl#42 at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:317
run_repl at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:305
#874 at .\client.jl:387
jfptr_YY.874_40889.clone_1 at C:\Program Files (x86)\Julia-1.6.1\lib\julia\sys.dll (unknown line)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1703 [inlined]
jl_f__call_latest at /cygdrive/c/buildbot/worker/package_win64/build/src\builtins.c:714
#invokelatest#2 at .\essentials.jl:708 [inlined]
invokelatest at .\essentials.jl:706 [inlined]
run_main_repl at .\client.jl:372
exec_options at .\client.jl:302
_start at .\client.jl:485
jfptr__start_22922.clone_1 at C:\Program Files (x86)\Julia-1.6.1\lib\julia\sys.dll (unknown line)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1703 [inlined]
true_main at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:560
repl_entrypoint at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:702
mainCRTStartup at /cygdrive/c/buildbot/worker/package_win64/build/cli\loader_exe.c:51
BaseThreadInitThunk at C:\WINDOWS\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\WINDOWS\SYSTEM32\ntdll.dll (unknown line)
Allocations: 34452269 (Pool: 34438096; Big: 14173); GC: 36

Reduced even more, in particular not using Tensors

using NLsolve

mutable struct Residuals{T} end

function noop(r::Residuals{T}, v::Vector{T}) where T
    return
end

function foo_crash(cache)
    res = nlsolve(cache, ones(14); (Dict{Symbol, Any}(:method=>:newton))...)
    x = Residuals{Float64}()
    noop(x, res.zero) # This call triggers it
end

A = rand(14, 14)
function f!(b, x)
    b[:] = A*x
end
cache = NLsolve.OnceDifferentiable(f!, rand(14), rand(14); autodiff=:forward)

foo_crash(cache)
  1. Crash does not happen if I change noop(x, res.zero) to noop(x, copy(res.zero)).
  2. Crash does not happen if I remove the type parameter on Residuals.

It shouldn’t, can you open an issue?

3 Likes

Thanks, here is the issue: https://github.com/JuliaLang/julia/issues/40912

2 Likes