On Sun, Feb 05, 2006 at 08:33:40PM +0900, Christian N. wrote:
least 1 other) it does get eventually raised after a few hundred
o=#Object:0x1d421c, i=ea10e, o2=:reject, n=448 (RuntimeError)
It looks like the object id wrapped in some way and now points to a
symbol? Clearly looks like a bug.
0x1d421c.to_s(2) # =>
“111010100001000011100”
0xea10e.to_s(2) # =>
“11101010000100001110”
0xea10e.class # => Fixnum
(2 * 0xea10e).to_s(2) # =>
“111010100001000011100”
So far so good.
Now, in gc.c:
static VALUE
id2ref(obj, id)
VALUE obj, id;
{
unsigned long ptr, p0;
rb_secure(4);
p0 = ptr = NUM2ULONG(id);
if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse;
if (ptr == Qnil) return Qnil;
if (FIXNUM_P(ptr)) return (VALUE)ptr;
if (SYMBOL_P(ptr) && rb_id2name(SYM2ID((VALUE)ptr)) != 0) {
return (VALUE)ptr;
}
(SYMBOL_FLAG == 0x0e)
NUM2ULONG is rb_num2ulong, which calls rb_num2long, which uses FIX2LONG.
id was 111010100001000011101b and ptr becomes 11101010000100001110b,
which
matches the SYMBOL_FLAG.
I’d conjecture that the above works on Linux because glibc’s malloc()
always
returns 8-byte aligned memory addresses, which doesn’t seem to be the
case in
OSX:
0x1d421c % 8 # => 4
Another possibility would be that the address space for the data segment
used in OSX is lower than on Linux, so the SYM2ID matches an existent
symbol:
RUBY_PLATFORM # => “i686-linux”
Object.new.inspect # =>
“#Object:0xb7d44d7c”
0xb7d44d7c >> 9 # => 6023718
we shouldn’t have 6 million symbols
0x1d421c >> 9 # => 3745
but 4000 are indeed possible
The relevant code hasn’t changed between 1.6 and 1.8; could it be that
the
Apple-supplied 1.6 binary was built specially to use 8-byte alignment,
or
that the memory layout has changed in the meantime?
If so, possible fixes would include:
- modifying the configure to use the magic options
- using posix_memalign or such