Bug #17606


Make failed on i386-cygwin (miniruby.exe aborted)

Added by fd0 (Daisuke Fujimura) 2 months ago. Updated about 1 month ago.

Target version:
ruby -v:
ruby 3.1.0dev (2021-02-01T20:20:34Z master 8ef30bcc04) [i386-cygwin]


Make failed on i386-cygwin (miniruby.exe aborted)

$ git clone
$ cd ruby
$ (./configure && make V=1) |& tee i386-cygwin-make.log 2>&1
./miniruby.exe -I./lib -I. -I.ext/common  ./tool/generic_erb.rb -c -o encdb.h ./template/encdb.h.tmpl ./enc enc
<internal:timev>:9: [BUG] vm_get_cref: unreachable
ruby 3.1.0dev (2021-02-01T20:20:34Z master 8ef30bcc04) [i386-cygwin]

-- Control frame information -----------------------------------------------
c:0002 p:0012 s:0006 e:000005 TOP    <internal:timev>:9 [FINISH]
c:0001 p:0000 s:0003 E:ffffe4f8 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
<internal:timev>:9:in `<internal:timev>'

-- Other runtime information -----------------------------------------------

* Loaded script: ./miniruby

* Loaded features:

    1 thread.rb
    5 ruby2_keywords.rb

make: *** [ encdb.h] Aborted (core dumped)

This problem seems to have occurred since e7fc353f044f9280222ca41b029b1368d2bf2fe3.

(I am aware that it may not be possible to fix it because of the absence of an active maintainer for cygwin.)


i386-cygwin-make.log (107 KB) i386-cygwin-make.log fd0 (Daisuke Fujimura), 02/02/2021 09:27 AM
ruby-iseq_inline_constant_cache_entry.patch (432 Bytes) ruby-iseq_inline_constant_cache_entry.patch xtkoba (Tee KOBAYASHI), 02/16/2021 12:12 AM

Updated by xtkoba (Tee KOBAYASHI) about 2 months ago

Consider the following code, in which all the assertions would be expected to hold:

#include <assert.h>
#include <stddef.h>

/* excerpts from rb_mjit_header.h */
typedef unsigned long VALUE;
typedef unsigned long long rb_serial_t;
typedef void *rb_cref_t; /* a pointer type */

/* from vm_core.h */
struct iseq_inline_constant_cache_entry {
    VALUE flags;

    VALUE value;              // v0
    const rb_cref_t *ic_cref; // v1
    rb_serial_t ic_serial;    // v2
                              // v3

/* from ractor.c */
struct RVALUE {
    VALUE flags;
    VALUE klass;
    VALUE v1;
    VALUE v2;
    VALUE v3;

int main() {
  assert(offsetof(struct iseq_inline_constant_cache_entry, flags) == offsetof(struct RVALUE, flags));
  assert(offsetof(struct iseq_inline_constant_cache_entry, value) == offsetof(struct RVALUE, klass));
  assert(offsetof(struct iseq_inline_constant_cache_entry, ic_cref) == offsetof(struct RVALUE, v1));

  /* the following assertion fails on i686-cygwin */
  assert(offsetof(struct iseq_inline_constant_cache_entry, ic_serial) == offsetof(struct RVALUE, v2));

  return 0;

Actually the last assertion does not hold, due to the padding in struct iseq_inline_constant_cache_entry.

A workaround is to use the pack pragma, as in the attached patch.

Updated by xtkoba (Tee KOBAYASHI) about 1 month ago

Strictly speaking, another assertion is needed to ensure that there be no padding between v2 and v3 of struct RVALUE:

  assert(offsetof(struct RVALUE, v3) == offsetof(struct RVALUE, v2) + sizeof(VALUE));

It will be desirable that compilers test these assertions statically and emit an error if any fails. I don't know whether there is a way to make them do so.

Another way of avoiding trouble with structure padding will be to implement the structure by an array and use macros to enable accessing its members by names.


Also available in: Atom PDF