Segfault on embedded ruby.

Discussion in 'Ruby' started by Godot, Jun 6, 2004.

  1. Godot

    Godot Guest

    Hi,
    This following problem is most likely due to my own
    misunderstandings, but I've not been able to resolve it after staring
    and scratching my head for quite a while. Here it is:

    ---------------Start code---------------

    #include <ruby.h>
    #include <iostream>
    #include <string>
    using namespace std;

    void dontCrash(string s)
    {
    VALUE test = rb_str_new2( s.c_str( ) );
    rb_gc_register_address(&test);
    rb_gc( ); // Test if gc gets corrupted
    rb_p( rb_str_new2(" stuff!!! ") );
    rb_p( test );
    rb_gc_unregister_address(&test);
    }

    int main ()
    {
    ruby_init ();
    ruby_init_loadpath ();
    dontCrash("puts 'test'");
    ruby_finalize();
    }

    -------------- End code --------------------

    The code (as reported by valgrind) always crashes on rb_gc( ).
    Without the rb_gc( ), the code runs fine. It also crashes when
    rb_register_address isn't called. This error has really got me
    stumped, so any help is greatly appreciated.

    Thanks,
    -Godot
     
    Godot, Jun 6, 2004
    #1
    1. Advertising

  2. Godot

    Paul Brannan Guest

    It doesn't crash for me.

    What platform (os, ruby version, compiler, etc.) are you using?

    Where in rb_gc() does the crash occur?

    Does valgrind report anything out of the ordinary? (you'll probably want
    to use a suppressions file such as the one in [ruby-talk:52065]).

    Paul
     
    Paul Brannan, Jun 7, 2004
    #2
    1. Advertising

  3. Godot

    Godot Guest


    > It doesn't crash for me.
    > What platform (os, ruby version, compiler, etc.) are you using?


    That's strange,
    Im using gentoo linux, ruby version emerged is 1.8.0-r6, compiling command
    is 'g++ testruby.cpp -g -lruby18 -I<ruby path>'
    Ive checked the version of ruby by printing out the defines
    RUBY_VERSION and RUBY_RELEASE_DATE, and the library/include matches up.

    Ive just tried it with ruby 1.8.1-r6 and this dumps as well.

    Hmm... This is stranger, it works with ruby 1.6.8. Has garbage collection
    management methods changed in between versions?

    > Where in rb_gc() does the crash occur?


    The following is from gdb, valgrind gives many errors, all related to
    rb_gc and rb_gc_mark_locations, but it is very verbose:

    Program received signal SIGSEGV, Segmentation fault.
    0x4007c683 in rb_gc_mark_locations () from /usr/lib/libruby18.so.1.8
    (gdb) bt
    #0 0x4007c683 in rb_gc_mark_locations () from /usr/lib/libruby18.so.1.8
    #1 0x4007e156 in rb_gc () from /usr/lib/libruby18.so.1.8
    #2 0x08048b18 in dontCrash(std::string) (s=Cannot access memory at address 0x0
    ) at testruby.cpp:12
    #3 0x08048b8f in main () at testruby.cpp:22


    Thanks again,
    -Godot
     
    Godot, Jun 7, 2004
    #3
  4. Godot

    Guest

    Hi,

    At Mon, 7 Jun 2004 04:33:40 +0900,
    Godot wrote in [ruby-talk:102597]:
    > ---------------Start code---------------
    >
    > #include <ruby.h>
    > #include <iostream>
    > #include <string>
    > using namespace std;

    extern "C" void Init_stack(VALUE*);
    >
    > void dontCrash(string s)
    > {
    > VALUE test = rb_str_new2( s.c_str( ) );
    > rb_gc_register_address(&test);
    > rb_gc( ); // Test if gc gets corrupted
    > rb_p( rb_str_new2(" stuff!!! ") );
    > rb_p( test );
    > rb_gc_unregister_address(&test);
    > }
    >
    > int main ()
    > {
    > ruby_init ();

    VALUE dummy;
    Init_stack(&dummy);
    > ruby_init_loadpath ();
    > dontCrash("puts 'test'");
    > ruby_finalize();
    > }


    --
    Nobu Nakada
     
    , Jun 8, 2004
    #4
  5. Godot

    Paul Brannan Guest

    On Tue, Jun 08, 2004 at 09:32:20AM +0900, wrote:
    > > int main ()
    > > {
    > > ruby_init ();

    > VALUE dummy;
    > Init_stack(&dummy);
    > > ruby_init_loadpath ();
    > > dontCrash("puts 'test'");
    > > ruby_finalize();
    > > }


    ruby_init() calls Init_stack, so why should this be necessary?

    Any why does it matter anyway whether the stack is properly initialized
    jn this case, since the address is being registered with the garbage
    collector? (and thus the object should be marked just fine)

    Paul
     
    Paul Brannan, Jun 8, 2004
    #5
  6. Godot

    Guest

    Hi,

    At Tue, 8 Jun 2004 12:24:31 +0900,
    Paul Brannan wrote in [ruby-talk:102734]:
    > > > int main ()
    > > > {
    > > > ruby_init ();

    > > VALUE dummy;
    > > Init_stack(&dummy);
    > > > ruby_init_loadpath ();
    > > > dontCrash("puts 'test'");
    > > > ruby_finalize();
    > > > }

    >
    > ruby_init() calls Init_stack, so why should this be necessary?


    To adjust the stack boundary.
    The stack frame inside Init_stack() called from ruby_init()
    would be placed at lower address than one of dontCrash() , so
    that `test' in it would be outside the region of GC target.

    --
    Nobu Nakada
     
    , Jun 8, 2004
    #6
  7. Godot

    Godot Guest

    On Tue, 08 Jun 2004 13:03:19 +0900, nobu.nokada wrote:

    > Hi,
    >
    > At Tue, 8 Jun 2004 12:24:31 +0900,
    > Paul Brannan wrote in [ruby-talk:102734]:
    >> > > int main ()
    >> > > {
    >> > > ruby_init ();
    >> > VALUE dummy;
    >> > Init_stack(&dummy);
    >> > > ruby_init_loadpath ();
    >> > > dontCrash("puts 'test'");
    >> > > ruby_finalize();
    >> > > }

    >>
    >> ruby_init() calls Init_stack, so why should this be necessary?

    >
    > To adjust the stack boundary.
    > The stack frame inside Init_stack() called from ruby_init()
    > would be placed at lower address than one of dontCrash() , so
    > that `test' in it would be outside the region of GC target.


    It works now :) Thanks for all the help, I don't think I would've
    come across that solution on my own. I'm still struggling to understand
    why 1.6.8-r10 didn't crash while 1.8* did, however.

    -Godot
     
    Godot, Jun 8, 2004
    #7
  8. Godot

    Paul Brannan Guest

    On Tue, Jun 08, 2004 at 01:03:19PM +0900, wrote:
    > > ruby_init() calls Init_stack, so why should this be necessary?

    >
    > To adjust the stack boundary.
    > The stack frame inside Init_stack() called from ruby_init()
    > would be placed at lower address than one of dontCrash() , so
    > that `test' in it would be outside the region of GC target.


    But test was marked with rb_gc_register_address(). Shouldn't that
    function work with addresses that are not on the stack?

    Paul
     
    Paul Brannan, Jun 8, 2004
    #8
  9. Godot

    ts Guest

    >>>>> "P" == Paul Brannan <> writes:

    P> But test was marked with rb_gc_register_address(). Shouldn't that
    P> function work with addresses that are not on the stack?

    this is when ruby mark the stack that it has a problem, but the example
    was badly written for an embedded application because it call ruby
    function without any protection (rb_protect(), etc)

    bad, bad, bad


    Guy Decoux
     
    ts, Jun 8, 2004
    #9
  10. Godot

    Godot Guest

    On Wed, 09 Jun 2004 00:35:37 +0900, ts wrote:

    >>>>>> "P" == Paul Brannan <> writes:

    >
    > P> But test was marked with rb_gc_register_address(). Shouldn't that
    > P> function work with addresses that are not on the stack?
    >
    > this is when ruby mark the stack that it has a problem, but the example
    > was badly written for an embedded application because it call ruby
    > function without any protection (rb_protect(), etc)
    >
    > bad, bad, bad
    >
    >
    > Guy Decoux


    Are you saying that I should rb_protect on rb_gc? Would that catch the
    fault? That doesn't seem possible - but when it comes to ruby, Alot of
    things that are seem impossible :)

    This was only an example illustrating a problem I was having on a larger
    application. It was by no means meant to be more than that, but I do
    appreciate the warning.

    -Godot
     
    Godot, Jun 8, 2004
    #10
  11. Godot

    Guest

    Hi,

    At Tue, 8 Jun 2004 23:40:36 +0900,
    Paul Brannan wrote in [ruby-talk:102783]:
    > > > ruby_init() calls Init_stack, so why should this be necessary?

    > >
    > > To adjust the stack boundary.
    > > The stack frame inside Init_stack() called from ruby_init()
    > > would be placed at lower address than one of dontCrash() , so
    > > that `test' in it would be outside the region of GC target.

    >
    > But test was marked with rb_gc_register_address(). Shouldn't that
    > function work with addresses that are not on the stack?


    I've understood that [ruby-talk:102597] doesn't crash when
    rb_gc_register_address() is called, wrong?

    At Mon, 7 Jun 2004 04:33:40 +0900,
    Godot wrote in [ruby-talk:102597]:
    > It also crashes when rb_register_address isn't called.


    --
    Nobu Nakada
     
    , Jun 8, 2004
    #11
  12. Godot

    ts Guest

    >>>>> "G" == Godot <> writes:

    G> Are you saying that I should rb_protect on rb_gc? Would that catch the
    G> fault? That doesn't seem possible - but when it comes to ruby, Alot of
    G> things that are seem impossible :)

    No, I was trying to say that your example was badly written. In an
    embedded application, after the initialization phase you must *never* make
    a call to a ruby function which is not protected with rb_protect(), or
    what you want.

    If ruby detect an error when it call a function, it will call longjmp()
    and this can crash your application if you have not made a previous call
    to rb_protect(), ...

    If your application is well written, you don't need Init_stack()


    Guy Decoux
     
    ts, Jun 9, 2004
    #12
  13. Godot

    Paul Brannan Guest

    On Wed, Jun 09, 2004 at 07:38:32AM +0900, wrote:
    > I've understood that [ruby-talk:102597] doesn't crash when
    > rb_gc_register_address() is called, wrong?


    Maybe I read it wrong, but I thought it crashed regardless of whether it
    was called.

    Paul
     
    Paul Brannan, Jun 9, 2004
    #13
  14. Godot

    Godot Guest

    On Thu, 10 Jun 2004 00:52:27 +0900, Paul Brannan wrote:

    > On Wed, Jun 09, 2004 at 07:38:32AM +0900, wrote:
    >> I've understood that [ruby-talk:102597] doesn't crash when
    >> rb_gc_register_address() is called, wrong?

    >
    > Maybe I read it wrong, but I thought it crashed regardless of whether it
    > was called.
    >
    > Paul



    That's correct, rb_gc_register_address doesn't prevent the crash, and the
    more I read about Init_stack, the more I question why it even needs to be
    called (although that does fix it).

    This is from http://www.rubygarden.org/ruby?RubyApi/InitStack :

    " If ruby_init() is not called from main(), you may need to use Init_stack
    so Ruby knows the true bounds of the stack."

    Now, either this wiki entry is only partially true, or ...?

    Clueless as usual,
    -Godot
     
    Godot, Jun 9, 2004
    #14
  15. Godot

    Guest

    Hi,

    At Thu, 10 Jun 2004 04:13:41 +0900,
    Godot wrote in [ruby-talk:102983]:
    > That's correct, rb_gc_register_address doesn't prevent the crash, and the
    > more I read about Init_stack, the more I question why it even needs to be
    > called (although that does fix it).


    Hmmm, rb_gc_register_address should do. Something other might
    go wrong.

    > This is from http://www.rubygarden.org/ruby?RubyApi/InitStack :
    >
    > " If ruby_init() is not called from main(), you may need to use Init_stack
    > so Ruby knows the true bounds of the stack."
    >
    > Now, either this wiki entry is only partially true, or ...?


    It is difficult to say generally without assembler details,
    because it is affected by compile option and so on.

    --
    Nobu Nakada
     
    , Jun 10, 2004
    #15
  16. Godot

    ts Guest

    >>>>> "n" == nobu nokada <> writes:

    n> Hmmm, rb_gc_register_address should do. Something other might
    n> go wrong.

    yes, there is something else

    n> It is difficult to say generally without assembler details,
    n> because it is affected by compile option and so on.

    you have found :)

    Now the original poster just need to write correctly its program.


    Guy Decoux
     
    ts, Jun 10, 2004
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Paul Gloster
    Replies:
    48
    Views:
    1,892
    Colin Paul Gloster
    Apr 10, 2007
  2. Andrey Vul
    Replies:
    8
    Views:
    687
    Richard Bos
    Jul 30, 2010
  3. Thomas Dodds

    Databind an embedded control in an embedded datagrid

    Thomas Dodds, Jul 26, 2004, in forum: ASP .Net Datagrid Control
    Replies:
    0
    Views:
    402
    Thomas Dodds
    Jul 26, 2004
  4. Nathan Whitney

    Segfault for Embedded socket.so

    Nathan Whitney, Jul 26, 2006, in forum: Ruby
    Replies:
    0
    Views:
    74
    Nathan Whitney
    Jul 26, 2006
  5. Trans
    Replies:
    11
    Views:
    302
    micathom
    Sep 5, 2007
Loading...

Share This Page