Hello,
I am not sure if this issue is similar / same like:
https://github.com/crystal-lang/crystal/issues/4916
From what I can tell, running a loop with different object types reads something incorrectly and receives signal 11:
Invalid memory access (signal 11) at address 0x8
[0x55685aace256] *CallStack::print_backtrace:Int32 +118
[0x55685aac27cb] __crystal_sigfault_handler +75
[0x7fa818e3bdd0] ???
[0x55685aab5bb5] __crystal_main +2101
[0x55685aac2ab6] *_crystal_main<Int32, Pointer(Pointer(UInt8))>:Nil +6
[0x55685ab0f136] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6
[0x55685ab0eff2] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +50
[0x55685aac0b66] main +6
[0x7fa81821af4a] __libc_start_main +234
[0x55685aab529a] _start +42
[0x0] ???
Code to reproduce is on play 47hw, but also included here:
module Base
getter parent : Base?
end
class Evnt
getter parent : Base
def initialize(@parent)
end
end
class MainObj
include Base
property event : Evnt?
end
o = MainObj.new
o.event = Evnt.new(o)
puts "Next two lines of output should be MainObj and Nil"
p o.event.not_nil!.parent.class
p o.parent.class
puts "Next line of output should be MainObj, and program should"
puts "then exit due to condition no longer being true"
puts "But the output is MainObj and MainObj, and program segfaults."
el = o.event.not_nil!
while el = el.parent
puts el.class
end
Crystal version is 0.24.2 binary tgz build from Crystal website.
Crystal 0.24.2 [4f9ed8d03] (2018-03-08)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu
Thanks!
Just for info, the same program converted to Ruby works fine:
module Base
attr_reader :parent
end
class Evnt
attr_reader :parent
def initialize(parent)
@parent = parent
end
end
class MainObj
include Base
attr_accessor :event
end
o = MainObj.new
o.event = Evnt.new(o)
puts "Next two lines of output should be MainObj and Nil"
p o.event.parent.class
p o.parent.class
puts "Next line of output should be MainObj, and program should"
puts "then exit due to condition no longer being true"
el = o.event
while el = el.parent
puts el.class
end
I've checked and the same issue appears on Crystal 0.25.0.
Here is a smaller reproducible test case (also on Play: https://play.crystal-lang.org/#/r/4dkk):
class Class1
property parent : self?
end
class Class2
# If the following property is optional/nilable (type "Class1?"), program works.
# If it is not optional (type "Class1"), it segfaults.
property parent : Class1
def initialize(@parent) end
end
c1 = Class1.new
c2 = Class2.new(c1)
el = c2.not_nil!
while el = el.parent
puts el.class
end
Most helpful comment
Here is a smaller reproducible test case (also on Play: https://play.crystal-lang.org/#/r/4dkk):