Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 04 May 2021 02:20:48 +0000
From:      bugzilla-noreply@freebsd.org
To:        ports-bugs@FreeBSD.org
Subject:   [Bug 255583] lang/ruby27: odd crash with certain "case" expressions on FreeBSD but not on Linux
Message-ID:  <bug-255583-7788@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D255583

            Bug ID: 255583
           Summary: lang/ruby27: odd crash with certain "case" expressions
                    on FreeBSD but not on Linux
           Product: Ports & Packages
           Version: Latest
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: Individual Port(s)
          Assignee: ruby@FreeBSD.org
          Reporter: sigsys@gmail.com
          Assignee: ruby@FreeBSD.org
             Flags: maintainer-feedback?(ruby@FreeBSD.org)

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

Dies with a SIGSEGV.

Backtrace (with a debug build):

* thread #1, name =3D 'ruby27', stop reason =3D signal SIGSEGV
    frame #0: 0x0000000801add4e8
libruby27.so.27`append_compile_error(iseq=3D0x000000089445a6b8, line=3D1125=
956,
fmt=3D"") at compile.c:380:47
    frame #1: 0x00007fffffffc930
  * frame #2: 0x0000000801c4d915 libruby27.so.27`rb_st_lookup [inlined]
do_hash(key=3D36847331000, tab=3D0x000000086f314d40) at st.c:326:33
    frame #3: 0x0000000801c4d90b
libruby27.so.27`rb_st_lookup(tab=3D0x000000086f314d40, key=3D36847331000,
value=3D0x00007fffffffc958) at st.c:1104
    frame #4: 0x0000000801b63443 libruby27.so.27`rb_hash_lookup2 [inlined]
hash_stlike_lookup(hash=3D36847330480, key=3D<unavailable>,
pval=3D0x00007fffffffc958) at hash.c:0
    frame #5: 0x0000000801b6339a
libruby27.so.27`rb_hash_lookup2(hash=3D36847330480, key=3D36847331000, def=
=3D8) at
hash.c:2070
    frame #6: 0x0000000801b0640a
libruby27.so.27`when_vals(iseq=3D0x000000089445a550, cond_seq=3D0x00007ffff=
fffcb60,
vals=3D0x0000000878b93098, l1=3D<unavailable>, only_special_literals=3D1,
literals=3D<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=3D0x000000089445a550,
ret=3D0x00007fffffffcd60, node=3D0x0000000878b93108, popped=3D0) at compile=
.c:7162
    frame #9: 0x0000000801b0ab71 libruby27.so.27`setup_args_core [inlined]
compile_args(node=3D0x0000000878b93140) at compile.c:3923:13
    frame #10: 0x0000000801b0ab59
libruby27.so.27`setup_args_core(iseq=3D0x000000089445a550,
args=3D0x00007fffffffcd60, argn=3D<unavailable>, dup_rest=3D<unavailable>,
flag=3D<unavailable>, keywords=3D0x00007fffffffcd28) at compile.c:5049
    frame #11: 0x0000000801af4dbf libruby27.so.27`iseq_compile_each0 [inlin=
ed]
compile_call(iseq=3D0x000000089445a550, ret=3D0x00007fffffffce80,
node=3D0x0000000878b93060, type=3D<unavailable>, line=3D1, popped=3D0) at
compile.c:7046:16
    frame #12: 0x0000000801af4ce1
libruby27.so.27`iseq_compile_each0(iseq=3D0x000000089445a550,
ret=3D0x00007fffffffce80, node=3D0x0000000878b93060, popped=3D0) at compile=
.c:7670
    frame #13: 0x0000000801adc735
libruby27.so.27`rb_iseq_compile_node(iseq=3D0x000000089445a550,
node=3D<unavailable>) at compile.c:702:6
    frame #14: 0x0000000801b85a47
libruby27.so.27`rb_iseq_new_with_opt(ast=3D0x000000089445a718,
name=3D<unavailable>, path=3D<unavailable>, realpath=3D<unavailable>, first=
_lineno=3D1,
parent=3D0x0000000819358010, type=3DISEQ_TYPE_MAIN, option=3D0x0000000801cf=
1d28) at
iseq.c:821:5
    frame #15: 0x0000000801b85b6d
libruby27.so.27`rb_iseq_new_main(ast=3D<unavailable>, path=3D<unavailable>,
realpath=3D<unavailable>, parent=3D<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=3D<unavailable>, argv=3D<unavaila=
ble>) at
ruby.c:2413
    frame #18: 0x0000000801b3f513
libruby27.so.27`ruby_options(argc=3D<unavailable>, argv=3D<unavailable>) at
eval.c:124:2
    frame #19: 0x0000000000201cca ruby27`main(argc=3D<unavailable>,
argv=3D<unavailable>) at main.c:50:23
    frame #20: 0x0000000000201a70 ruby27`_start(ap=3D<unavailable>,
cleanup=3D<unavailable>) at crt1.c:76:7

It happens whenever a rational literal is used as a branch in a case
expression.  Happens during the parse/compile phase (e.g. when "require"'in=
g a
file with a construct like that).  With both package and port.  I tested on
12.2-RELEASE, 12.2-STABLE and 14-CURRENT and they all have the problem.

The problem started happening recently but I'm not sure when or due to what
changes.

It doesn't happen if Ruby is built with GCC (e.g. by setting USE_GCC=3Dyes =
in the
port).

Looks like it's a case of Clang's optimizer being a bit more aggressive (an=
d/or
header macros being defined in a way that leads to that).

Patch:

diff --git c/lang/ruby27/files/patch-compile.c
i/lang/ruby27/files/patch-compile.c
new file mode 100644
index 000000000000..c766600b8f40
--- /dev/null
+++ i/lang/ruby27/files/patch-compile.c
@@ -0,0 +1,20 @@
+--- compile.c.orig     2021-04-05 08:39:38.000000000 -0400
++++ compile.c  2021-05-03 20:49:59.011745000 -0400
+@@ -1820,7 +1820,7 @@
+         return rb_float_cmp(lit, val);
+     }
+     else {
+-        UNREACHABLE_RETURN(-1);
++        return -1;
+     }
+ }
+=20
+@@ -1838,7 +1838,7 @@
+       case T_FLOAT:
+         return rb_dbl_long_hash(RFLOAT_VALUE(a));
+       default:
+-        UNREACHABLE_RETURN(0);
++        return 0;
+     }
+ }
+=20

The default branches there are NOT unreachable and Clang eliding them seems=
 to
be causing a runaway program counter.

There's actually a flaw in Ruby there that causes a pessimization of the ha=
sh
table optimization for the literals of a switch because the hash table does=
n't
properly handles all numeric types (but it still tries to insert them in it=
),
but it harmlessly fallsback to testing the branches one by one.

lang/ruby26 and lang/ruby30 have the same problem and could use the same pa=
tch.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-255583-7788>