Frame-pointer omission and ruby (was Bug in Ruby Ext to C or it is me ?)

Hello Nobu,
Everytime i’ve tried to build ruby with “-O3 -mcpu=i586 -march=k6 -ffast-math -fomit-frame-pointer” with gcc-2.95.2, gcc-2.95.3, gcc-3.01, and gcc-3.1, miniruby has crashed during the building of the default extensions. All I have to do to make it work is take out the “-fomit-frame-pointer”. This has happened on windoze with mingw32 and cygwin, mandrake 6.2, 7.2, and 8.2, vector linux 2.0 (a slackware based mini-distro), and gentoo-linux 1.2. I have set the compiler flags via the $CFLAGS environment variable.
Also yesterday I started having crashes with the C++ bindings for ruby I’m working on, and after a full-day of debugging I tracked it down to having the frame-pointer ommitted by the “maximise speed” optimisation of my MSVC project. As soon as I turned it on (i.e. started generating frame-pointers) everything worked perfectly. Eventually I did this via the “pragma optimise” command in a header, so that anything that includes it gets the frame-pointer generated.
The crashes only began happening after I started wrapping all ruby calls and macros with rb_protect(). Note that I am embedding ruby in a c++ prog, and so cannot allow ruby exceptions to be thrown over c++ code because the stack will not be unwound correctly. I translate the ruby exceptions to c++ exceptions.
I also notice that the msvc makefile for ruby has a fairly carefully selected set of compiler flags that leaves frame-pointer generation turned on.
That said, I have compiled serveral extensions (such as ruby-fltk, fxruby, and some of my own) with frame-pointer generation off, and they have worked perfectly too.
Perhaps yourself or Matz could shed some light on this?

···

On Thu, 12 Sep 2002 14:32:17 +0900 nobu.nokada@softhome.net wrote:

Hi,

At Thu, 12 Sep 2002 08:50:04 +0900, > Lorien Dunn wrote:

I bet you have compiled with stack-frame-pointer ommision
turned on. This is done with -fomit-frame-pointer in gcc, and
is the default with MSVC when you choose the “Maximise Speed”
optimisation. Frame-pointer ommision does not work with ruby
exceptions or threads.

I usually use gcc with that option, rather it may be concerned
with platform and compiler version.


Nobu Nakada

Opps,
the flags I meant were “-O2 -mcpu=k6 -march=i586 -ffast-math -fomit-frame-pointer” (I got -mcpu and -march back-to-front). The reason that I’m not using -march=k6 is because telling gcc versions earlier than 3.1 to generate k6-specific instructions just makes programs crash :(.

BTW where can I find the 1.6.7 back port of the windoze structured exception handling recently added to 1.7.3?

Thanks,
Lorien Dunn

···

On Thu, 12 Sep 2002 22:14:25 +0900 Lorien Dunn loriend@bigpond.com wrote:

Everytime i’ve tried to build ruby with “-O3 -mcpu=i586 -march=k6 -ffast-math -fomit-frame-pointer” with gcc-2.95.2, gcc-2.95.3, gcc-3.01, and

“Lorien Dunn” loriend@bigpond.com wrote in message
news:20020910175108.6e7f62eb.loriend@bigpond.com


Ruby itself is compiled (under mswin32 with VC) with framepointer
optimization but not global optimization (which is really unfortunate
see [ruby-core:323/324 and 422] ).

/Christoph

Hi,

···

At Thu, 12 Sep 2002 22:14:25 +0900, Lorien Dunn wrote:

Everytime i’ve tried to build ruby with “-O3 -mcpu=i586
-march=k6 -ffast-math -fomit-frame-pointer” with gcc-2.95.2,
gcc-2.95.3, gcc-3.01, and gcc-3.1, miniruby has crashed
during the building of the default extensions. All I have to
do to make it work is take out the “-fomit-frame-pointer”.

Some versions of gcc have a bug that wrong code is emitted for
__builtin_frame_address() with -fomit-frame-pointer.

And, sorry that I forgot that I’ve applied this patch.

Or a patch in [ruby-dev:17947] may help.

Index: configure.in

RCS file: /cvs/ruby/src/ruby/configure.in,v
retrieving revision 1.139
diff -u -2 -p -r1.139 configure.in
— configure.in 8 Sep 2002 09:04:15 -0000 1.139
+++ configure.in 8 Sep 2002 12:56:58 -0000
@@ -306,4 +306,16 @@ AC_STRUCT_ST_BLOCKS
AC_STRUCT_ST_RDEV

+AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address,
+[rb_cv_stack_end_address=no
+for addr in __libc_stack_end _SEND; do

  • AC_TRY_LINK(
  • [extern void *$addr;],
  • [if (!$addr) return 1;],
  • [rb_cv_stack_end_address=“$addr”; break])
    +done])
    +if test $rb_cv_stack_end_address != no; then
  • AC_DEFINE_UNQUOTED(STACK_END_ADDRESS, $rb_cv_stack_end_address)
    +fi

dnl Checks for library functions.
AC_TYPE_GETGROUPS
Index: gc.c

RCS file: /cvs/ruby/src/ruby/gc.c,v
retrieving revision 1.103
diff -u -2 -p -r1.103 gc.c
— gc.c 6 Sep 2002 08:59:38 -0000 1.103
+++ gc.c 6 Sep 2002 15:42:59 -0000
@@ -31,4 +31,8 @@
#endif

+#if defined _WIN32 || defined CYGWIN
+#include <windows.h>
+#endif
+
void re_free_registers _((struct re_registers*));
void rb_io_fptr_finalize _((struct OpenFile*));
@@ -1195,7 +1199,13 @@ Init_stack(addr)
VALUE *addr;
{
-#if defined(human68k)

  • extern void *_SEND;
  • rb_gc_stack_start = _SEND;
    +#if defined(_WIN32) || defined(CYGWIN)
  • MEMORY_BASIC_INFORMATION m;
  • memset(&m, 0, sizeof(m));
  • VirtualQuery(&m, &m, sizeof(m));
  • /* assume stack growing downward */
  • rb_gc_stack_start = (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1;
    +#elif defined(STACK_END_ADDRESS)
  • extern void *STACK_END_ADDRESS;
  • rb_gc_stack_start = STACK_END_ADDRESS;
    #else
    VALUE start;


Nobu Nakada

My mistake,
I only get miniruby crashing with -fomit-frame-pointer with ruby-1.6.6 and below. 1.6.7 checked out from cvs a few minutes ago seems fine. This is on gentoo linux with gcc-2.95.3 20010315 (release). I’ll experiment on windoze with msvc6 sp5 later today.

Thanks,
Lorien Dunn

···

On Thu, 12 Sep 2002 14:32:17 +0900 > nobu.nokada@softhome.net wrote:

I usually use gcc with that option, rather it may be concerned
with platform and compiler version.


Nobu Nakada

Lorien Dunn wrote:

BTW where can I find the 1.6.7 back port of the windoze structured exception handling recently added to 1.7.3?

You’ll need to check out the ruby_1_6 branch from CVS. See the CVS
instructions linked from the Ruby home page.