Crash/stackoverflow when calling constructor with too many inputs

question

#1

I’m writing some code where I define vectors and points in homogeneous coordinates. To this end, I inherit from StaticArrays.FieldVector with length N+1, in order to enforce the invariant that the last coordinate be equal to 1.

The code has been working fine for a while, then I started experiencing that Julia would suddenly close without warning. I’m not sure exactly what’s going on, but I have recreated similar behaviour in the below examples. The behaviour occurs when I call the type constructors with too many inputs. Presumably, some behaviour is inherited from the supertype, causing the problems.

The problem progresses in severity with the number of dimensions. In example 1, I get a simple ‘ambiguous method’ error. In example 2, I get stack overflow error (which prints 80,000 times!), and in example 3, Julia closes immediately without warning.

using StaticArrays

struct Dummy1D{T<:Real} <: FieldVector{2, T}
    x::T
    y::T
    Dummy1D{T}(x) where {T} = new{T}(x, one(T))
end

struct Dummy2D{T<:Real} <: FieldVector{3, T}
    x::T
    y::T
    z::T
    Dummy2D{T}(x, y) where {T} = new{T}(x, y, one(T))
end

struct Dummy3D{T<:Real} <: FieldVector{4, T}
    x::T
    y::T
    z::T
    w::T
    Dummy3D{T}(x, y, z) where {T} = new{T}(x, y, z, one(T))
end

The errors:

Main> Dummy1D{Int}(1,2)
ERROR: MethodError: Dummy1D{Int64}(::Tuple{Int64,Int64}) is ambiguous. Candidates:
  (::Type{Dummy1D{T}})(x) where T in Main at none:4
  (::Type{FV})(x::Tuple) where FV<:StaticArrays.FieldVector in StaticArrays at /Users/dnf/.julia/v0.6/StaticArrays/src/FieldVector.jl:20
Possible fix, define
  (::Type{Dummy1D{T}})(::Tuple)
Stacktrace:
 [1] Dummy1D{Int64}(::Int64, ::Int64) at /Users/dnf/.julia/v0.6/StaticArrays/src/convert.jl:3
 [2] eval(::Module, ::Any) at ./boot.jl:235

Main> Dummy2D{Int}(1,2,3)
ERROR: StackOverflowError...
...
...
[79994] Dummy2D{Int64}(::Tuple{Int64,Int64,Int64}) at /Users/dnf/.julia/v0.6/StaticArrays/src/FieldVector.jl:20
[79995] Dummy2D{Int64}(::Int64, ::Int64, ::Int64) at /Users/dnf/.julia/v0.6/StaticArrays/src/convert.jl:3
[79996] Dummy2D{Int64}(::Tuple{Int64,Int64,Int64}) at /Users/dnf/.julia/v0.6/StaticArrays/src/FieldVector.jl:20
[79997] Dummy2D{Int64}(::Int64, ::Int64, ::Int64) at /Users/dnf/.julia/v0.6/StaticArrays/src/convert.jl:3

Main> Dummy2D{Int}(1,2,3,4)
<Julia closes without warning>

Main> Dummy3D{Int}(1,2,3,4)
<Julia closes without warning>

In these cases I deliberately call the constructors with too many arguments. In the original code I don’t do that, but I suspect that with the increasing number of complicated constructors I’ve made to cover all use cases, somehow, that behaviour is inadvertently triggered.

Is the above behaviour expected?

Edit: Oh, BTW, version 0.6.1.


#2

I would consider this a StaticArrays bug. Issue opened: https://github.com/JuliaArrays/StaticArrays.jl/issues/342


#3

But Julia should not crash. Or is StaticArrays doing some unsafe stuff under the hood?


#4

I frequently observe Julia crashing when stack overflow occurs, including in situations which do not involve StaticArrays.


#5

(though I of course agree that it should not)


#6

Probably relevant: https://github.com/JuliaLang/julia/issues/23126#issuecomment-320165678


#7

Okay, should be fixed on StaticArrays master. You can run Pkg.checkout("StaticArrays") to try it out.