Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#8 Segfaults on undefined methods

open
None
5
2004-04-20
2004-04-20
No

I get "segmentation faults" instead of "undefined local
variable or method". Well, I get that from time to time
when I make a typo in a method name, and it's
consistent in the sense that a typo always gives the
error, but not every typo does. I never encountered this
in Ruby before though I'm great at making typos. My
Ruby version is "ruby 1.8.1 (2004-02-06) [i686-linux-gnu]
", RUDL version is 0.7.1, SDL version is 1.2.6. (They're all
Gentoo ebuilds.) Even this tiny prog generates the error:

require 'RUDL'
surf = RUDL::DisplaySurface.new([1024, 768], 32)
surf.put("toto")

This does not:

require 'RUDL'
surf = RUDL::DisplaySurface.new([1024, 768], 32)
surf = ""
surf.put("toto")

This does:

require 'RUDL'
surf = RUDL::DisplaySurface.new([1024, 768], 32)
surf = [surf]
surf.put("toto")

Also it doesn't occur when I try it in irb.

Discussion

1 2 > >> (Page 1 of 2)
  • Tom Copeland
    Tom Copeland
    2004-07-15

    Logged In: YES
    user_id=5159

    I bet this is happening because there's no "put" method on
    DisplaySurface - as far as I can tell from
    rudl_video_display_surface.c - and so when you call it,
    there's nowhere for the call to go and bad things happen.

    Perhaps we could add in a method_missing definition around
    line 666 of rudl_video_display_surface.c to keep it from
    crashing?

    Or maybe I'm missing something very obvious, which is
    equally possible :-)

    Yours,

    Tom

     
  • Tom Copeland
    Tom Copeland
    2004-07-15

    Logged In: YES
    user_id=5159

    Here's a little patch to prevent segfaults on this
    particular class... perhaps a better way to do this would be
    to do this on a superclass or something:

    [tom@hal rudl]$ cvs diff rudl_video_display_surface.c
    Index: rudl_video_display_surface.c
    ===================================================================
    RCS file: /cvsroot/rudl/rudl/rudl_video_display_surface.c,v
    retrieving revision 1.23
    diff -r1.23 rudl_video_display_surface.c
    443a444,450
    > static VALUE displaySurface_method_missing(int argc,
    VALUE* argv, VALUE self)
    > {
    > printf("Unknown method
    (possible mispeling?) invoked on DisplaySurface, exiting
    now.\n");
    > SDL_RAISE;
    > return self;
    > }
    >
    792a800
    > rb_define_method(classDisplaySurface,
    "method_missing", displaySurface_method_missing, -1);
    [tom@hal rudl]$

    Disclaimer: my C coding skills are wayyy rusty, so this code
    is lousy.

    Yours,

    Tom

     
  • Logged In: YES
    user_id=412977

    I am afraid I can't reproduce this... The patch should not be
    needed since every RUDL object is based on Ruby's "Object."
    That provides the method_missing method. There is something
    really nasty happening on your side... Hmmm, I'm passing this
    bug to Renne, who might have Linux running.

     
  • Tom Copeland
    Tom Copeland
    2004-07-26

    Logged In: YES
    user_id=5159

    > since every RUDL object is based on Ruby's "Object."

    Hm, yup, that makes sense. I wonder why adding a
    method_missing would prevent that segfault then?

    > I'm passing this bug to Renne

    Cool...

    Tom

     
  • Brian
    Brian
    2004-07-27

    Logged In: YES
    user_id=1079855

    I get the same problem on Windows, except I get the
    old 'The application has requested the runtime to terminate in
    an unusual way' message.

    From prior experience on other Windows C projects, this
    message almost always occurs when you are mixing versions
    of the CRT (C Run-Time Library) -- for instance, perhaps
    Ruby was compiled with the 'Static Release' version, while
    RUDL was compiled with the 'DLL Release' or the 'Static
    Debug Multi-threaded' version.

    Unfortunately, I'm not sure how this translates to linux and
    GCC -- are there multiple versions of the CRT on GCC as well?

     
  • Tom Copeland
    Tom Copeland
    2004-07-27

    Logged In: YES
    user_id=5159

    > are there multiple versions of the CRT on GCC as well?

    Dunno about that... I compiled RUDL on Linux using the
    Makefile that's in CVS.

    It's odd that the problem goes away when I patch in a
    method_missing. As Danny said, it seems that, say,
    DisplaySurface should extend Object and inherit
    method_missing. Hm. I wonder what happens if I modify
    DisplaySurface to explicitly extend Object?

    Tom

     
  • Tom Copeland
    Tom Copeland
    2004-07-27

    Logged In: YES
    user_id=5159

    > I wonder what happens if I modify
    > DisplaySurface to explicitly extend Object?

    Bah, it pretty much does that already since it extends
    Surface which extends rb_cObject, as it were. Hmmm. I'm
    all out of ideas...

    Tom

     
  • Tom Copeland
    Tom Copeland
    2004-07-27

    Logged In: YES
    user_id=5159

    Well I'll be darned... it appears that Surface does not, in
    fact, define method_missing. I don't know how it doesn't
    inherit it from Object, but anyhow, I modified
    rudl_video_surface.c - tweaked inspect() to print all public
    methods:

    " \"<Surface: #{w}x#{h},#{bitsize}>
    #{public_methods.join(\"\\n\")}\" \n"

    Now when I do a:

    [tom@hal rudl]$ ruby -e "require 'RUDL'; puts
    RUDL::Surface.new([1,1]).inspect" | grep method
    singleton_methods
    method
    protected_methods
    private_methods
    public_methods
    methods
    [tom@hal rudl]$

    Weird, huh? No method_missing!

    Or maybe it's me that's missing something here... probably.

    Yours,

    Tom

     
  • Tom Copeland
    Tom Copeland
    2004-07-27

    Logged In: YES
    user_id=5159

    Hm. Digging further, Object does an rb_include_module to
    get the Kernel stuff. So it seems like Surface should
    inherit that.... maybe? Dunno. But if I change inspect()
    in rudl_video_surface.c to look like this:

    " def inspect \n"
    " \"<Surface: #{w}x#{h},#{bitsize}>
    #{foobar}\" \n"
    " end

    i.e., trying to call an unknown method "foobar" I get this:

    [tom@hal rudl]$ ruby -e "require 'RUDL'; puts
    RUDL::Surface.new([1,1]).inspect" | grep method
    (eval):92:in `inspect'(eval):92: [BUG] Segmentation fault
    ruby 1.8.1 (2003-12-25) [i686-linux]

    Odd.

    Tom

     
  • Brian
    Brian
    2004-07-27

    Logged In: YES
    user_id=1079855

    method_missing is a private method on all objects
    call Surface::new.private_methods and you'll see
    method_missing, it's there. This is the same on any object,
    which I just verified (for my sake) with this code:

    vvvvvvvvvvv
    class TC
    def g
    end
    end

    puts TC::new.methods.sort # doesn't contain
    method_missing
    puts TC.::new.private_methods.sort # contains
    method_missing
    ^^^^^^^^^

    But I'm as baffled as you are, why does it crash when it is
    called?

    I think it's interesting that calling a non-existent method on
    an array that simply _contains_ a surface causes a segfault,
    even though you're not calling the method on the surface
    itself. I created an array:

    f = [7, 6, Surface::new([50,55]), 6, 8]
    f.put # causes a segfault

    but

    g = Surface::new([50,55])
    f = [7, 6, 4, 7]
    f.put # no segfault

     
1 2 > >> (Page 1 of 2)