ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
@ 2021-01-14  4:34 xtkoba+ruby
  2021-01-14  9:50 ` [ruby-core:102087] " shyouhei
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-01-14  4:34 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been reported by xtkoba (Tee KOBAYASHI).

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102087] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
@ 2021-01-14  9:50 ` shyouhei
  2021-02-28  4:17 ` [ruby-core:102651] " xtkoba+ruby
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: shyouhei @ 2021-01-14  9:50 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by shyouhei (Shyouhei Urabe).


Mmm… That sounds like an LLVM issue.  At least in the latest C++, `volatile` is deprecated.  I don’t think that fix works for extension libraries written in that language.


cf: http://wg21.link/P1152

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-89945

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102651] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
  2021-01-14  9:50 ` [ruby-core:102087] " shyouhei
@ 2021-02-28  4:17 ` xtkoba+ruby
  2021-03-01  2:16 ` [ruby-core:102673] " xtkoba+ruby
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-02-28  4:17 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


Here is an alternative workaround which inserts a memory barrier into the function `rb_str_vcatf` from `sprintf.c`:
```
--- a/sprintf.c
+++ b/sprintf.c
@@ -1227,6 +1227,7 @@
     f._bf._base = (unsigned char *)str;
     f._p = (unsigned char *)RSTRING_END(str);
     klass = RBASIC(str)->klass;
+    __asm__ __volatile__ ("" : : : "memory");
     RBASIC_CLEAR_CLASS(str);
     f.vwrite = ruby__sfvwrite;
     f.vextra = ruby__sfvextra;
```

Without the memory barrier, the flow of `rb_str_vcatf` looks as follows:
```
Breakpoint 1, rb_str_vcatf (str=str@entry=1024669056, fmt=0x3fc64e95 " %s>", ap=...) at ../sprintf.c:1222
1222        StringValue(str);
1223        rb_str_modify(str);
1226        f._w = rb_str_capacity(str);
1225        f._bf._size = 0;
1224        f._flags = __SWR | __SSTR;
1226        f._w = rb_str_capacity(str);
1228        f._p = (unsigned char *)RSTRING_END(str);
1227        f._bf._base = (unsigned char *)str;
1228        f._p = (unsigned char *)RSTRING_END(str);
1226        f._w = rb_str_capacity(str);
1228        f._p = (unsigned char *)RSTRING_END(str);
1232        f.vwrite = ruby__sfvwrite;
1233        f.vextra = ruby__sfvextra;
1228        f._p = (unsigned char *)RSTRING_END(str);
1231        RBASIC_CLEAR_CLASS(str);
1232        f.vwrite = ruby__sfvwrite;
1233        f.vextra = ruby__sfvextra;
1228        f._p = (unsigned char *)RSTRING_END(str);
1229        klass = RBASIC(str)->klass;
1234        buffer.value = 0;
1233        f.vextra = ruby__sfvextra;
1235        BSD_vfprintf(&f, fmt, ap);
1232        f.vwrite = ruby__sfvwrite;
1235        BSD_vfprintf(&f, fmt, ap);
1236        RBASIC_SET_CLASS_RAW(str, klass);
1237        rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
1236        RBASIC_SET_CLASS_RAW(str, klass);
1237        rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
1240        return str;
(gdb) p *(struct RBasic *)str
$1 = {flags = 8197, klass = 0}
```

With the memory barrier, the flow becomes as follows:
```
Breakpoint 1, rb_str_vcatf (str=str@entry=1024669056, fmt=0x3fc64e95 " %s>", ap=...) at ../sprintf.c:1222
1222        StringValue(str);
1223        rb_str_modify(str);
1226        f._w = rb_str_capacity(str);
1225        f._bf._size = 0;
1224        f._flags = __SWR | __SSTR;
1226        f._w = rb_str_capacity(str);
1228        f._p = (unsigned char *)RSTRING_END(str);
1227        f._bf._base = (unsigned char *)str;
1228        f._p = (unsigned char *)RSTRING_END(str);
1226        f._w = rb_str_capacity(str);
1228        f._p = (unsigned char *)RSTRING_END(str);
1229        klass = RBASIC(str)->klass;
1230        __asm__ __volatile__ ("" : : : "memory");
1231        RBASIC_CLEAR_CLASS(str);
1232        f.vwrite = ruby__sfvwrite;
1233        f.vextra = ruby__sfvextra;
1232        f.vwrite = ruby__sfvwrite;
1231        RBASIC_CLEAR_CLASS(str);
1233        f.vextra = ruby__sfvextra;
1234        buffer.value = 0;
1233        f.vextra = ruby__sfvextra;
1232        f.vwrite = ruby__sfvwrite;
1235        BSD_vfprintf(&f, fmt, ap);
1236        RBASIC_SET_CLASS_RAW(str, klass);
1237        rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
1236        RBASIC_SET_CLASS_RAW(str, klass);
1237        rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
1240        return str;
(gdb) p *(struct RBasic *)str
$1 = {flags = 8197, klass = 1062619968}
```

And yes, this looks pretty much a bug of Clang/LLVM to me for now. I'm going to create a minimal reproducing example to send to Clang/LLVM maintainers. One more push...

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90644

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102673] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
  2021-01-14  9:50 ` [ruby-core:102087] " shyouhei
  2021-02-28  4:17 ` [ruby-core:102651] " xtkoba+ruby
@ 2021-03-01  2:16 ` xtkoba+ruby
  2021-03-01 22:32 ` [ruby-core:102680] " xtkoba+ruby
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-03-01  2:16 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


MWE:
``` c
#include <stdarg.h>
#include <assert.h>

#ifndef WORKAROUND
#define WORKAROUND 0
#endif

typedef unsigned long VALUE;

static void RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
{
    struct { VALUE flags; VALUE klass; } *ptr = (void *)obj;
    ptr->klass = klass;
}

struct RBasic {
    VALUE flags;
    /*const*/ VALUE klass;
};

#define RBASIC(obj) ((struct RBasic *)(obj))

struct RString {
    struct RBasic basic;
    union {
        struct { long len; char *ptr; } heap;
        char ary[8];
    } as;
};

/* dummy function */
#pragma clang optimize off
static int dummy_vfprintf(char *fmt, va_list ap) { return 0; }
#pragma clang optimize on

#define NOP __asm__ __volatile__ ("nop")

VALUE rb_str_catf(VALUE str, char *format, ...)
{
    va_list ap;
    __builtin_va_start(ap, format);
    struct RString buf;
    if (RBASIC(str)->flags & 0x2000) { NOP; }
    else {
        buf.as.heap.ptr = ((struct RString *)str)->as.ary;
    }
    if (__builtin_expect(!!(! buf.as.heap.ptr), 0)) { NOP; }
    VALUE klass = RBASIC(str)->klass;
#if WORKAROUND
    __asm__ __volatile__ ("" : : : "memory");
#endif
    RBASIC_SET_CLASS_RAW(str, 0);
    dummy_vfprintf(format, ap);
    RBASIC_SET_CLASS_RAW(str, klass);
    __builtin_va_end(ap);
    return str;
}

int main()
{
    struct RBasic obj = { .flags = 0, .klass = 1 };
    rb_str_catf((VALUE)&obj, "");
    assert(obj.klass == 1);
    return 0;
}
```
The assertion fails when compiled with `-DWORKAROUND=0`, and holds with `-DWORKAROUND=1`.

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90667

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102680] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (2 preceding siblings ...)
  2021-03-01  2:16 ` [ruby-core:102673] " xtkoba+ruby
@ 2021-03-01 22:32 ` xtkoba+ruby
  2021-03-01 22:47 ` [ruby-core:102681] " XrXr
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-03-01 22:32 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


A ticket in LLVM Bugzilla: https://bugs.llvm.org/show_bug.cgi?id=49384

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90674

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102681] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (3 preceding siblings ...)
  2021-03-01 22:32 ` [ruby-core:102680] " xtkoba+ruby
@ 2021-03-01 22:47 ` XrXr
  2021-03-01 23:14 ` [ruby-core:102683] " xtkoba+ruby
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: XrXr @ 2021-03-01 22:47 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by alanwu (Alan Wu).


This seems like a strict aliasing issue. I'm curious if compiling with `-fno-strict-aliasing` fixes it.

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90675

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102683] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (4 preceding siblings ...)
  2021-03-01 22:47 ` [ruby-core:102681] " XrXr
@ 2021-03-01 23:14 ` xtkoba+ruby
  2021-03-01 23:26 ` [ruby-core:102684] " XrXr
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-03-01 23:14 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


user:alanwu Ah yes, it seems to fix the issue, at least for the MWE code. Thanks for the suggestion!

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90677

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102684] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (5 preceding siblings ...)
  2021-03-01 23:14 ` [ruby-core:102683] " xtkoba+ruby
@ 2021-03-01 23:26 ` XrXr
  2021-03-02  1:08 ` [ruby-core:102688] " shyouhei
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: XrXr @ 2021-03-01 23:26 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by alanwu (Alan Wu).


If this fixes the Ruby crash too, maybe we should make put `-fno-strict-aliasing` as a default compilation option like the Linux kernel. It's very easy to make strict aliasing mistakes and they are too hard to spot...

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90678

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102688] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (6 preceding siblings ...)
  2021-03-01 23:26 ` [ruby-core:102684] " XrXr
@ 2021-03-02  1:08 ` shyouhei
  2021-03-02  3:13 ` [ruby-core:102690] " xtkoba+ruby
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: shyouhei @ 2021-03-02  1:08 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by shyouhei (Shyouhei Urabe).


I suspect commit:d0e0c884bb4277e529adbd8d82aae0a651f7edf2 could be the cause of this issue.

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90683

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102690] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (7 preceding siblings ...)
  2021-03-02  1:08 ` [ruby-core:102688] " shyouhei
@ 2021-03-02  3:13 ` xtkoba+ruby
  2021-03-02  6:30 ` [ruby-core:102697] " shyouhei
  2021-03-02  6:49 ` [ruby-core:102698] " xtkoba+ruby
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-03-02  3:13 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


Compilation with `-fno-strict-aliasing` seems to resolve the main issue of the `ruby` crash. It would be nice if this compiler option is added by default, unless it causes a serious performance drawback.

user:shyouhei That change might have induced the issue, but I don't think it is the fundamental cause. The trouble would be that the type `struct RBasic` has aliases. In this point of view, yet another workaround would be as follows (although I don't know whether the attribute `may_alias` works with C++):
```
--- a/include/ruby/internal/core/rbasic.h
+++ b/include/ruby/internal/core/rbasic.h
@@ -66,7 +66,7 @@ RBasic {
     {
     }
 #endif
-};
+} __attribute__ ((__may_alias__));
 
 RBIMPL_SYMBOL_EXPORT_BEGIN()
 VALUE rb_obj_hide(VALUE obj);
```

FYI, some searching told me that CPython had a similar issue until version 2.7 with its object representation in C (cf. https://bugs.python.org/issue30104).

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90685

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [ruby-core:102697] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (8 preceding siblings ...)
  2021-03-02  3:13 ` [ruby-core:102690] " xtkoba+ruby
@ 2021-03-02  6:30 ` shyouhei
  2021-03-02  6:49 ` [ruby-core:102698] " xtkoba+ruby
  10 siblings, 0 replies; 12+ messages in thread
From: shyouhei @ 2021-03-02  6:30 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by shyouhei (Shyouhei Urabe).


This is my take:

```patch
From 7fb39b1138dfaa3a1502673ac82d6b75401e8f39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@ruby-lang.org>
Date: Tue, 2 Mar 2021 15:22:22 +0900
Subject: [PATCH] fix strict aliasing

---
 internal/object.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/internal/object.h b/internal/object.h
index aa820128c7..6a5dfcda63 100644
--- a/internal/object.h
+++ b/internal/object.h
@@ -47,8 +47,8 @@ MJIT_SYMBOL_EXPORT_END
 static inline void
 RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
 {
-    struct { VALUE flags; VALUE klass; } *ptr = (void *)obj;
-    ptr->klass = klass;
+    VALUE *ptr =(/* const cast */VALUE *) & RBASIC(obj)->klass;
+    memcpy(ptr, &klass, sizeof(klass));
 }
 
 static inline void
-- 
2.17.1

```

I would like to reflain from fixing this issue by adding compiler-specific `__asm__` or `__attreibute__`, because that does not help everyone...  The world is not built on top of LLVM.  I don't want to kill support for other compiler infrastructures.

It sounds like a nice idea to have `-fno-strict-aliasing`, though.  That is just a matter of compiler flag.  Must not hurt the codebase.

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90692

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [ruby-core:102698] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux
  2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
                   ` (9 preceding siblings ...)
  2021-03-02  6:30 ` [ruby-core:102697] " shyouhei
@ 2021-03-02  6:49 ` xtkoba+ruby
  10 siblings, 0 replies; 12+ messages in thread
From: xtkoba+ruby @ 2021-03-02  6:49 UTC (permalink / raw)
  To: ruby-core

Issue #17540 has been updated by xtkoba (Tee KOBAYASHI).


user:shyouhei Thanks, it works. I have no objection to avoiding compiler-specific keywords, as long as things go well without them.

----------------------------------------
Bug #17540: A segfault due to Clang/LLVM optimization on 32-bit ARM Linux 
https://bugs.ruby-lang.org/issues/17540#change-90693

* Author: xtkoba (Tee KOBAYASHI)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [armv7a-linux-eabi]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
When built with `optflags=-O3` (which is the default), `ruby -e "pp Thread.main"` causes a segfault, which seems to be worked around by the following change:
```
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -231,7 +231,7 @@
 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
 RBIMPL_ATTR_ARTIFICIAL()
 static inline VALUE
-RB_FL_TEST_RAW(VALUE obj, VALUE flags)
+RB_FL_TEST_RAW(volatile VALUE obj, VALUE flags)
 {
     RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
     return RBASIC(obj)->flags & flags;
```

There might be a bug in the optimizer of Clang/LLVM (version 11.0.1).



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-03-02  6:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-14  4:34 [ruby-core:102083] [Ruby master Bug#17540] A segfault due to Clang/LLVM optimization on 32-bit ARM Linux xtkoba+ruby
2021-01-14  9:50 ` [ruby-core:102087] " shyouhei
2021-02-28  4:17 ` [ruby-core:102651] " xtkoba+ruby
2021-03-01  2:16 ` [ruby-core:102673] " xtkoba+ruby
2021-03-01 22:32 ` [ruby-core:102680] " xtkoba+ruby
2021-03-01 22:47 ` [ruby-core:102681] " XrXr
2021-03-01 23:14 ` [ruby-core:102683] " xtkoba+ruby
2021-03-01 23:26 ` [ruby-core:102684] " XrXr
2021-03-02  1:08 ` [ruby-core:102688] " shyouhei
2021-03-02  3:13 ` [ruby-core:102690] " xtkoba+ruby
2021-03-02  6:30 ` [ruby-core:102697] " shyouhei
2021-03-02  6:49 ` [ruby-core:102698] " xtkoba+ruby

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).