[Bug #1267] DL::Handle#sym segfaults with nil

Bug #1267: DL::Handle#sym segfaults with nil
http://redmine.ruby-lang.org/issues/show/1267

e$B5/I<<Te(B: Nobuyoshi N.
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
e$B%+%F%4%je(B: ext, Target version: 1.9.1
ruby -v: ruby 1.9.2dev (2009-03-11 trunk 22881) [i386-darwin9.0]

DL::Handle#syme$B$K%7%s%%kL>$H$7$Fe(Bnile$B$rEO$9$HBe$o$j$Ke(BRTLD_NEXTe$B$r;He(B
e$B$&$h$&$K$J$C$F$$$^$9$,!"e(BRTLD_NEXTe$B$,EO$;$k$N$O%7%s%%kL>$G$O$J$/e(B
e$B$FBh0l0z?t$N%O%s%I%k$N$[$&$G$9!#e(B

e$B%O%s%I%k$K3:Ev$9$k$N$Oe(Bselfe$B$G$9$,!"$b$A$m$se(Bnile$B$OEO$7$h$&$,$G$-$Je(B
e$B$$$N$G%/%i%9%a%=%C%I$rDj5A$9$k$N$O$I$&$G$7$g$&$+!#e(B

$ ruby -rdl -e ‘p DL::Handle.new(“libc.dylib”).sym(nil)’
-e:1: [BUG] Segmentation fault
ruby 1.9.2dev (2009-03-11 trunk 22881) [i386-darwin9.0]

– control frame ----------
c:0004 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :sym
c:0003 p:0027 s:0007 b:0006 l:001fc4 d:001d84 EVAL -e:1
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:001fc4 d:001fc4 TOP :45920

-e:1:in <main>' -e:1:in sym’

– C level backtrace information

[NOTE]
You may have encountered a bug in the Ruby interpreter. Bug reports are
welcome.
For details: http://www.ruby-lang.org/bugreport.html

Abort trap

e$B%A%1%C%He(B #1267 e$B$,99?7$5$l$^$7$?!#e(B (by Nobuyoshi N.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r22891.

http://redmine.ruby-lang.org/issues/show/1267

e$B$J$+$@$G$9!#e(B

At Wed, 11 Mar 2009 18:40:15 +0900,
Nobuyoshi N. wrote in [ruby-dev:38150]:

DL::Handle#syme$B$K%7%s%%kL>$H$7$Fe(Bnile$B$rEO$9$HBe$o$j$Ke(BRTLD_NEXTe$B$r;He(B
e$B$&$h$&$K$J$C$F$$$^$9$,!"e(BRTLD_NEXTe$B$,EO$;$k$N$O%7%s%%kL>$G$O$J$/e(B
e$B$FBh0l0z?t$N%O%s%I%k$N$[$&$G$9!#e(B

SEGVe$B$9$k$N$OLdBj$J$N$G$H$j$"$($:e(Bnile$B$N07$$$OH4$-$^$7$?!#e(B

e$B%O%s%I%k$K3:Ev$9$k$N$Oe(Bselfe$B$G$9$,!"$b$A$m$se(Bnile$B$OEO$7$h$&$,$G$-$Je(B
e$B$$$N$G%/%i%9%a%=%C%I$rDj5A$9$k$N$O$I$&$G$7$g$&$+!#e(B

e$B$3$A$i$O2~$a$Fe(Bfeature requeste$B$H$$$&$3$H$G!#e(B

Index: ext/dl/handle.c

— ext/dl/handle.c (revision 22891)
+++ ext/dl/handle.c (working copy)
@@ -130,17 +130,11 @@ rb_dlhandle_to_i(VALUE self)
}

+static VALUE dlhandle_sym(void *handle, const char *symbol);
+
VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{

  • void (*func)();
    struct dl_handle *dlhandle;

  • void *handle;
    const char *name;
    -#if defined(HAVE_DLERROR)

  • const char *err;
    -# define CHECK_DLERROR if( err = dlerror() ){ func = 0; }
    -#else
    -# define CHECK_DLERROR
    -#endif

    rb_secure(2);
    @@ -152,7 +146,31 @@ rb_dlhandle_sym(VALUE self, VALUE sym)
    rb_raise(rb_eDLError, “closed handle”);
    }

  • handle = dlhandle->ptr;

  • func = dlsym(handle, name);

  • return dlhandle_sym(dlhandle->ptr, StringValuePtr(sym));
    +}

+VALUE
+rb_dlhandle_s_sym(VALUE self, VALUE sym)
+{
+#ifdef RTLD_NEXT

  • void *handle = RTLD_NEXT;
    +#else
  • void *handle = NULL;
    +#endif
  • rb_secure(2);
  • return dlhandle_sym(handle, StringValuePtr(sym));
    +}

+static VALUE
+dlhandle_sym(void *handle, const char *name)
+{
+#if defined(HAVE_DLERROR)

  • const char *err;
    +# define CHECK_DLERROR if( err = dlerror() ){ func = 0; }
    +#else
    +# define CHECK_DLERROR
    +#endif
  • void (*func)() = dlsym(handle, name);
  • CHECK_DLERROR;
    #if defined(FUNC_STDCALL)
    @@ -209,4 +227,6 @@ Init_dlhandle(void)
    rb_cDLHandle = rb_define_class_under(rb_mDL, “Handle”, rb_cObject);
    rb_define_alloc_func(rb_cDLHandle, rb_dlhandle_s_allocate);
  • rb_define_singleton_method(rb_cDLHandle, “sym”, rb_dlhandle_s_sym,
    1);
  • rb_define_singleton_method(rb_cDLHandle, “[]”, rb_dlhandle_s_sym,
    1);
    rb_define_method(rb_cDLHandle, “initialize”,
    rb_dlhandle_initialize, -1);
    rb_define_method(rb_cDLHandle, “to_i”, rb_dlhandle_to_i, 0);