I'm playing with porting Ruby to Stratus VOS, which is an unusual but
POSIX-supporting x86 platform.
My first build problem was a crash in miniruby, in gc.c. In a nutshell,
gc.c is relying on __builtin_frame_pointer but is not setting
-fno-omit-frame-pointer. This causes a crash, but I'm not sure what the
proper semantics of these two are and if I should (a) submit a patch for
Ruby in autoconf, or (b) submit a patch to Stratus for a bug in their gcc
implementation (currently at 3.3.1).
Details:
gc.c, post-preprocessor, looks like this:
__attribute__ ((noinline)) static VALUE * stack_end_address(void)
{ return (VALUE *) __builtin_frame_address(0); }
typedef unsigned long VALUE;
...
static void garbage_collect() {
VALUE *stack_end = stack_end_address();
...
rb_gc_mark_locations((VALUE*)(stack_end), rb_gc_stack_start);
...
}
void rb_gc_mark_locations(start, end)
VALUE *start, *end;
...
Somehow, this ends up calling rb_gc_mark_locations with a weird stack_end:
#1 0x0003c98b in rb_gc_mark_locations (
start=0x172378,
end=0x40010ee0)
at gc.c:642
#2 0x0003ddff in garbage_collect ()
at gc.c:1368
(gdb) f 1
(gdb) p start
$3 = (VALUE *) 0x1000
(gdb) p &start
Address requested for identifier "start" which is in register $edx
Even though stack_end itself looks reasonable:
(gdb) f 2
#2 0x0003ddff in garbage_collect ()
at gc.c:1368
1368 rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start);
(gdb) p stack_end
$3 = (
VALUE *) 0x400eb8d0
Now, I would *think* that either you have frame pointers, or you don't.
And, looking at stack_end, we seem to - but we can't seem to pass it
anywhere.
OTOH, I imagine that calling __builtin_frame_pointer but defining
-fomit-frame-pointer is "undefined behavior".
On the third hand, I see at least one package (kaffe) has moved away from
__builtin_frame_pointer in favor of "some assember" due to GCC bugs.
Anyone know a few things about this?
--
Jay Levitt |
Boston, MA | My character doesn't like it when they
Faster: jay at jay dot fm | cry or shout or hit.
http://www.jay.fm | - Kristoffer