crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.45k stars 1.62k forks source link

Invalid memory access (signal 11) at address 0x178 with Enumerable in non-release mode #14047

Open docelic opened 11 months ago

docelic commented 11 months ago

Bug Report

crystal  -v
Crystal 1.10.1 [c6f3552f5] (2023-10-13)

LLVM: 15.0.7
Default target: x86_64-unknown-linux-gnu

The following code crashes:

class VTime

  alias Virtual = Nil | Enumerable(Int32)

  property year        : Virtual   # <-- With only this property, it works
  property month    : Virtual  # <-- With this property, it crashes with long error message
  property day         : Virtual   # <-- With this property, it crashes with short error message
end

t = VTime.new
x = 0..20
#p x            # <-- If print is here, it works; without it, it crashes; see notes below
t.year = x
p t

(Code on play: https://play.crystal-lang.org/#/r/g6c0)

Output from running this code:

  1. If only 1 property is defined in class (only the first one), it works:
crystal run --error-trace  bug.cr
#<VTime:0x7b049b17ff30 @year= ...>
  1. If two properties are defined, it crashes with long error msg:
crystal run --error-trace  bug.cr
#<VTime:0x786a5ebb2b00 @year=Invalid memory access (signal 11) at address 0x100000040
[0x58e9f187b876] *Exception::CallStack::print_backtrace:Nil +118 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f186af96] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil) +310 in .cache/crystal/crystal-run-bug.tmp
[0x786a5f10a730] ?? +132398256793392 in /lib/x86_64-linux-gnu/libpthread.so.0
[0x58e9f18f68d4] *VTime +1044 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f186b2a6] *p<VTime>:VTime +22 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f185acd9] __crystal_main +1161 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f18f8806] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f18f877a] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +58 in .cache/crystal/crystal-run-bug.tmp
[0x58e9f1868256] main +6 in .cache/crystal/crystal-run-bug.tmp
[0x786a5ecdb09b] __libc_start_main +235 in /lib/x86_64-linux-gnu/libc.so.6
[0x58e9f185a78a] _start +42 in .cache/crystal/crystal-run-bug.tmp
[0x0] ???
  1. If three properties are defined, it crashes with short error msg:
crystal run --error-trace  bug.cr
#<VTime:0x722250591d80 @year=Invalid memory access (signal 11) at address 0x178
[0x62aeff54e876] *Exception::CallStack::print_backtrace:Nil +118 in .cache/crystal/crystal-run-bug.tmp
[0x62aeff53df96] Program exited because of an invalid memory access
  1. But if the Range is printed before being assigned to t.year, then it doesn't crash:
t = VTime.new
x = 0..20
p x       # <-- enable this
t.year = x
p t
crystal run --error-trace  bug.cr
0..20
#<VTime:0x7705336a5d80 @year=false, @day=nil>

(Note: originally my alias Virtual had more types than the shortened example shown above. With more types, adding/removing p x was making a difference between working/crashing. After I reduced the alias to just Nil | Enumerable(Int32), the p x no longer had effect - it always crashes.)

  1. If -Dpreview_mt is specified, the behavior is slightly different, but the same. (With -Dpreview_mt it crashes on more than 2 properties, not just more than one).

  2. The code doesn't crash in any combination if it is run in release mode:

crystal run --error-trace --release bug.cr
#<VTime:0x721caa944d80 @year=nil, @month=nil, @day=nil>
  1. The issue somehow seems related to Enumerable(Int). If I use e.g. Range(Int,Int) instead of that, then it doesn't crash.
HertzDevil commented 11 months ago

Looks related to #10518

docelic commented 3 months ago

For reference, on 1.13.1 the same code from the initial report still crashes. Also, it doesn't seem affected by the p x line, crash always happens:

crystal  test5.cr
0..20
#<VTime:0x732d607f7d80 @year=[Invalid memory access (signal 11) at address 0x4
[0x613036fa4de6] *Exception::CallStack::print_backtrace:Nil +118 in /.cache/crystal/crystal-run-test5.tmp
[0x613036f93776] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil) +310 in /.cache/crystal/crystal-run-test5.tmp
[0x732d60933050] ?? +126638730981456 in /lib/x86_64-linux-gnu/libc.so.6
[0x61303704bedc] *Array(Int32) +412 in /.cache/crystal/crystal-run-test5.tmp
[0x61303704bd36] *Array(Int32) +6 in /.cache/crystal/crystal-run-test5.tmp
[0x61303704b6ca] *VTime +922 in /.cache/crystal/crystal-run-test5.tmp
[0x613036f94386] *p<VTime>:VTime +22 in /.cache/crystal/crystal-run-test5.tmp
[0x613036f83cae] __crystal_main +1134 in /.cache/crystal/crystal-run-test5.tmp
[0x613036fe0826] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6 in /.cache/crystal/crystal-run-test5.tmp
[0x613036fe079a] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +58 in /.cache/crystal/crystal-run-test5.tmp
[0x613036f911b6] main +6 in /.cache/crystal/crystal-run-test5.tmp
[0x732d6091e24a] ?? +126638730895946 in /lib/x86_64-linux-gnu/libc.so.6
[0x732d6091e305] __libc_start_main +133 in /lib/x86_64-linux-gnu/libc.so.6
[0x613036f83771] _start +33 in /.cache/crystal/crystal-run-test5.tmp
[0x0] ???