Bug #17606
closedMake failed on i386-cygwin (miniruby.exe aborted)
Description
Make failed on i386-cygwin (miniruby.exe aborted)
$ git clone https://github.com/ruby/ruby.git
$ cd ruby
$ (./configure && make V=1) |& tee i386-cygwin-make.log 2>&1
(snip)
./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:
0 enumerator.so
1 thread.rb
2 fiber.so
3 rational.so
4 complex.so
5 ruby2_keywords.rb
make: *** [uncommon.mk:1098: 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.)
Files
Updated by xtkoba (Tee KOBAYASHI) over 3 years 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) over 3 years 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.
Updated by xtkoba (Tee KOBAYASHI) over 3 years ago
Updated by xtkoba (Tee KOBAYASHI) over 3 years ago
- Status changed from Open to Closed
Applied in changeset git|121fa24a3451b45c41ac0a661b64e9fc8600e589.
Adjust struct member offset for i386 Cygwin
Fixes [Bug #17606]