Project

General

Profile

Actions

Bug #17854

closed

Crash with certain "case" expressions on FreeBSD

Added by meta@vmeta.jp (Koichiro Iwao) over 3 years ago. Updated over 3 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 2.7.3p183 (2021-04-05 revision 6847ee089d) [amd64-freebsd13]
[ruby-core:103759]

Description

Affected version

  • Ruby 2.6, 2.7, 3.0 compiled with clang on FressBD

No tested with other versions. Ruby compiled with GCC doesn't have this issue.

Snippet to reproduce

ruby -e 'case 1; when 2r; 3; end'

Step to reproduce

Prepare a fresh installation of FreeBSD 13. Either Ruby installed from system package or ruby-build can reproduce the issue.

# clang -v 
FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
Target: x86_64-unknown-freebsd13.0
Thread model: posix
InstalledDir: /usr/bin
[root@ruby-bug /tmp]# clang -v 
FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
Target: x86_64-unknown-freebsd13.0
Thread model: posix
InstalledDir: /usr/bin

System Ruby

# pkg install ruby 
# /usr/local/bin/ruby -v
# /usr/local/bin/ruby -e 'case 1; when 2r; 3; end'

Ruby installed by ruby-build

Same as Ruby installed by ruby-build.

# pkg install rbenv ruby-build
# bash
bash# eval "$(rbenv init -)"
bash# cd /tmp
bash# rbenv install 2.7.3
bash# rbenv local 2.7.3
bash# rbenv which ruby
/root/.rbenv/versions/2.7.3/bin/ruby
bash# ruby -e 'case 1; when 2r; 3; end'

Backtrace (submitted by the original reporter)


Backtrace (with a debug build):

* thread #1, name = 'ruby27', stop reason = signal SIGSEGV
    frame #0: 0x0000000801add4e8 libruby27.so.27`append_compile_error(iseq=0x000000089445a6b8, line=1125956, fmt="") at compile.c:380:47
    frame #1: 0x00007fffffffc930
  * frame #2: 0x0000000801c4d915 libruby27.so.27`rb_st_lookup [inlined] do_hash(key=36847331000, tab=0x000000086f314d40) at st.c:326:33
    frame #3: 0x0000000801c4d90b libruby27.so.27`rb_st_lookup(tab=0x000000086f314d40, key=36847331000, value=0x00007fffffffc958) at st.c:1104
    frame #4: 0x0000000801b63443 libruby27.so.27`rb_hash_lookup2 [inlined] hash_stlike_lookup(hash=36847330480, key=<unavailable>, pval=0x00007fffffffc958) at hash.c:0
    frame #5: 0x0000000801b6339a libruby27.so.27`rb_hash_lookup2(hash=36847330480, key=36847331000, def=8) at hash.c:2070
    frame #6: 0x0000000801b0640a libruby27.so.27`when_vals(iseq=0x000000089445a550, cond_seq=0x00007fffffffcb60, vals=0x0000000878b93098, l1=<unavailable>, only_special_literals=1, literals=<unavailable>) at compile.c:4322:18
    frame #7: 0x0000000801afac70 libruby27.so.27`iseq_compile_each0 at compile.c:5334:27
    frame #8: 0x0000000801afa5c1 libruby27.so.27`iseq_compile_each0(iseq=0x000000089445a550, ret=0x00007fffffffcd60, node=0x0000000878b93108, popped=0) at compile.c:7162
    frame #9: 0x0000000801b0ab71 libruby27.so.27`setup_args_core [inlined] compile_args(node=0x0000000878b93140) at compile.c:3923:13
    frame #10: 0x0000000801b0ab59 libruby27.so.27`setup_args_core(iseq=0x000000089445a550, args=0x00007fffffffcd60, argn=<unavailable>, dup_rest=<unavailable>, flag=<unavailable>, keywords=0x00007fffffffcd28) at compile.c:5049
    frame #11: 0x0000000801af4dbf libruby27.so.27`iseq_compile_each0 [inlined] compile_call(iseq=0x000000089445a550, ret=0x00007fffffffce80, node=0x0000000878b93060, type=<unavailable>, line=1, popped=0) at compile.c:7046:16
    frame #12: 0x0000000801af4ce1 libruby27.so.27`iseq_compile_each0(iseq=0x000000089445a550, ret=0x00007fffffffce80, node=0x0000000878b93060, popped=0) at compile.c:7670
    frame #13: 0x0000000801adc735 libruby27.so.27`rb_iseq_compile_node(iseq=0x000000089445a550, node=<unavailable>) at compile.c:702:6
    frame #14: 0x0000000801b85a47 libruby27.so.27`rb_iseq_new_with_opt(ast=0x000000089445a718, name=<unavailable>, path=<unavailable>, realpath=<unavailable>, first_lineno=1, parent=0x0000000819358010, type=ISEQ_TYPE_MAIN, option=0x0000000801cf1d28) at iseq.c:821:5
    frame #15: 0x0000000801b85b6d libruby27.so.27`rb_iseq_new_main(ast=<unavailable>, path=<unavailable>, realpath=<unavailable>, parent=<unavailable>) at iseq.c:787:12
    frame #16: 0x0000000801c40537 libruby27.so.27`ruby_process_options at ruby.c:1904:9
    frame #17: 0x0000000801c3f433 libruby27.so.27`ruby_process_options(argc=<unavailable>, argv=<unavailable>) at ruby.c:2413
    frame #18: 0x0000000801b3f513 libruby27.so.27`ruby_options(argc=<unavailable>, argv=<unavailable>) at eval.c:124:2
    frame #19: 0x0000000000201cca ruby27`main(argc=<unavailable>, argv=<unavailable>) at main.c:50:23
    frame #20: 0x0000000000201a70 ruby27`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7

Patch

The following patch is provided by the original reporter but it looks too ad-hoc. If this bug is fixed in Ruby upstream, I'll apply it to FreeBSD package.

diff --git a/compile.c b/compile.c
index 1cabb8c..a954176 100644
--- a/compile.c
+++ b/compile.c
@@ -1987,7 +1987,7 @@ cdhash_cmp(VALUE val, VALUE lit)
         return rb_float_cmp(lit, val);
     }
     else {
-        UNREACHABLE_RETURN(-1);
+        return -1;
     }
 }
 
@@ -2005,7 +2005,7 @@ cdhash_hash(VALUE a)
       case T_FLOAT:
         return rb_dbl_long_hash(RFLOAT_VALUE(a));
       default:
-        UNREACHABLE_RETURN(0);
+        return 0;
     }
 }

See also

Downstream bug:


Files

trace.log (37.5 KB) trace.log meta@vmeta.jp (Koichiro Iwao), 05/06/2021 11:51 AM

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #17857: `when 0r` and `when 0i` do not match with `case 0`ClosedActions
Actions #1

Updated by meta@vmeta.jp (Koichiro Iwao) over 3 years ago

  • Description updated (diff)
Actions #2

Updated by meta@vmeta.jp (Koichiro Iwao) over 3 years ago

  • Description updated (diff)

Updated by mame (Yusuke Endoh) over 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to shyouhei (Shyouhei Urabe)

Thank you for the detailed report.

I confirm the issue on Ubuntu by adding logging code before UNREACHABLE_RETURN(-1).

diff --git a/compile.c b/compile.c
index 1cabb8cccd..826d9c6f4a 100644
--- a/compile.c
+++ b/compile.c
@@ -1987,6 +1987,7 @@ cdhash_cmp(VALUE val, VALUE lit)
         return rb_float_cmp(lit, val);
     }
     else {
+        puts("check2");
         UNREACHABLE_RETURN(-1);
     }
 }
@@ -2005,6 +2006,7 @@ cdhash_hash(VALUE a)
       case T_FLOAT:
         return rb_dbl_long_hash(RFLOAT_VALUE(a));
       default:
+        puts("check1");
         UNREACHABLE_RETURN(0);
     }
 }
$ ./miniruby -e 'case 1; when 2r; when 2r; end'
check1
check1
check1
check2
check1
check2
check1
check1
check2
check1
check1
check2

The code in question was introduced by @shyouhei (Shyouhei Urabe) at the 33c8171c65ac0f66d1c096561e253f6f068fc85c. @shyouhei (Shyouhei Urabe) could you please check this out?

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

Thank you for reporting! This is my bug, clang optimizer is not guilty here.

Trying to fix at: https://github.com/ruby/ruby/pull/4469

Actions #5

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

  • Status changed from Assigned to Closed

Applied in changeset git|2bc293e899c9d32dcd794a73de8925c49ecf8f15.


cdhash_cmp: can take rational literals

Rational literals are those integers suffixed with r. They tend to
be a part of more complex expressions like 123/456r, but in theory
they can live alone. When such "bare" rational literals are passed to
case-when branch, we have to take care of them. Fixes [Bug #17854]

Actions #6

Updated by mame (Yusuke Endoh) over 3 years ago

  • Related to Bug #17857: `when 0r` and `when 0i` do not match with `case 0` added

Updated by meta@vmeta.jp (Koichiro Iwao) over 3 years ago

Any chances to be backported to each supported version?

Actions #8

Updated by nagachika (Tomoyuki Chikanaga) over 3 years ago

  • Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: UNKNOWN, 2.7: REQUIRED, 3.0: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) over 3 years ago

  • Backport changed from 2.6: UNKNOWN, 2.7: REQUIRED, 3.0: REQUIRED to 2.6: UNKNOWN, 2.7: REQUIRED, 3.0: DONE

ruby_3_0 31816356eee6313fe968eecd4cd3ad9ac4848819 merged revision(s) 2bc293e899c9d32dcd794a73de8925c49ecf8f15,d0e6c6e682b9ba2b0309a5177933a0628e8ef316,cc0dc67bbbe1951ff90004bc987f78545625d772,e1eff837cf12a8e813de9d4ff2db50c9b68b86b5,0ab0b86c8491d639b9ff1335ddf35e341ecd867e,6911b4bc82889860ff7da4ecf975504cdc3e5314.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0