From: Jeff Mitchell Date: 2004-05-20T01:07:23+09:00 Subject: [PATCH] ruby/dl ext/dl/ptr.c:26: static void rb_dlmem_delete(void *ptr) { rb_secure(4); rb_hash_delete(DLMemoryTable, DLLONG2NUM(ptr)); } Eventually ptr crosses the boundary of fixnum, causing a bignum to be created. It appears to be an error to create a non-immediate VALUE while inside a free() function (memory corruption or segfault). Here's my attempted fix. Note that I change the keys of DLMemoryTable. From what I could decipher from the Japanese documentation, it doesn't appear that DLMemoryTable is part of the API. There was also a memory leak in dlptr_free(). Index: ext/dl/dl.h =================================================================== RCS file: /src/ruby/ext/dl/dl.h,v retrieving revision 1.9 diff -u -r1.9 dl.h --- ext/dl/dl.h 1 Dec 2003 23:02:44 -0000 1.9 +++ ext/dl/dl.h 19 May 2004 06:38:03 -0000 @@ -210,6 +210,9 @@ # define DLNUM2LONG(x) (long)(NUM2INT(x)) #endif +#define DLPTR2FIX(x) LONG2FIX(((unsigned long)(x)) >> 1) +#define DLFIX2PTR(x) ((void*)(FIX2ULONG(x) << 1)) + typedef struct { char c; void *x; } s_voidp; typedef struct { char c; short x; } s_short; typedef struct { char c; int x; } s_int; Index: ext/dl/ptr.c =================================================================== RCS file: /src/ruby/ext/dl/ptr.c,v retrieving revision 1.19 diff -u -r1.19 ptr.c --- ext/dl/ptr.c 22 Oct 2003 14:29:20 -0000 1.19 +++ ext/dl/ptr.c 19 May 2004 06:38:03 -0000 @@ -9,6 +9,8 @@ VALUE rb_cDLPtrData; VALUE rb_mDLMemorySpace; + +/* keys are shifted pointers to fit into fixnums */ static VALUE DLMemoryTable; #ifndef T_SYMBOL @@ -27,7 +29,7 @@ rb_dlmem_delete(void *ptr) { rb_secure(4); - rb_hash_delete(DLMemoryTable, DLLONG2NUM(ptr)); + rb_hash_delete(DLMemoryTable, DLPTR2FIX(ptr)); } static void @@ -37,7 +39,7 @@ rb_dlmem_delete(ptr); } else{ - rb_hash_aset(DLMemoryTable, DLLONG2NUM(ptr), DLLONG2NUM(obj)); + rb_hash_aset(DLMemoryTable, DLPTR2FIX(ptr), DLLONG2NUM(obj)); } } @@ -46,7 +48,7 @@ { VALUE val; - val = rb_hash_aref(DLMemoryTable, DLLONG2NUM(ptr)); + val = rb_hash_aref(DLMemoryTable, DLPTR2FIX(ptr)); return val == Qnil ? Qnil : (VALUE)DLNUM2LONG(val); } @@ -69,6 +71,7 @@ if (data->stype) dlfree(data->stype); if (data->ssize) dlfree(data->ssize); if (data->ids) dlfree(data->ids); + free(data); } void @@ -1013,7 +1016,7 @@ VALUE key, val; key = rb_ary_entry(assoc, 0); val = rb_ary_entry(assoc, 1); - rb_yield(rb_assoc_new(key,(VALUE)DLNUM2LONG(val))); + rb_yield(rb_assoc_new(ULONG2NUM(FIX2PTR(key)),(VALUE)DLNUM2LONG(val))); return Qnil; } __________________________________ Do you Yahoo!? SBC Yahoo! - Internet access at a great low price. http://promo.yahoo.com/sbc/