Hi,

At Mon, 10 Jan 2005 19:23:03 +0900,
ts wrote in [ruby-core:04171]:
> n> There are some kinds of callbacks, as mentioned in [ruby-core:04160].
> 
>  Well, I've no idea actually about this, but I want to know : it's
>  voluntary the memory leak in sym.c, or I'm wrong and it don't exist a
>  memory leak ?

Do you mean, in rb_dlsym_call(), the case that "to_ptr"
conversion failed, and that copied strings for 's' arguments
don't get freed?


Index: ext/dl/sym.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/dl/sym.c,v retrieving revision 1.27 diff -U2 -p -r1.27 sym.c --- ext/dl/sym.c 21 Dec 2004 23:34:43 -0000 1.27 +++ ext/dl/sym.c 10 Jan 2005 13:47:03 -0000 @@ -267,10 +267,9 @@ rb_dlsym_inspect(VALUE self) str_size = RSTRING(proto)->len + 100; - str = dlmalloc(str_size); - snprintf(str, str_size - 1, + val = rb_tainted_str_new(0, str_size); + snprintf(RSTRING(val)->ptr, str_size, "#<DL::Symbol:0x%p func=0x%p '%s'>", sym, sym->func, RSTRING(proto)->ptr); - val = rb_tainted_str_new2(str); - dlfree(str); + RSTRING(val)->len = strlen(RSTRING(val)->ptr); return val; @@ -467,5 +466,14 @@ rb_dlsym_call(int argc, VALUE argv[], VA dargs = ALLOC_N(ANY_TYPE, sym->len - 1); dtypes = ALLOC_N(int, sym->len - 1); -#define FREE_ARGS {xfree(args); xfree(dargs); xfree(dtypes);} +#define FREE_ARGS_FROM_I do { \ + do { \ + if( dtypes[i] == 's' && ANY2S(args[i]) ){ \ + dlfree((void *)ANY2S(args[i])); \ + ANY2S(args[i]) = 0; \ + } \ + } while (++i <= sym->len - 2); \ + xfree(args); xfree(dargs); xfree(dtypes); \ + } while (0) +#define FREE_ARGS do {i = 0; FREE_ARGS_FROM_I; } while (0) for( i = sym->len - 2; i >= 0; i-- ){ @@ -490,4 +498,5 @@ rb_dlsym_call(int argc, VALUE argv[], VA pval = rb_funcall(argv[i], rb_intern("to_ptr"), 0); if( !rb_obj_is_kind_of(pval, rb_cDLPtrData) ){ + FREE_ARGS_FROM_I; rb_raise(rb_eDLTypeError, "unexpected type of argument #%d", i); } @@ -596,5 +605,5 @@ rb_dlsym_call(int argc, VALUE argv[], VA break; default: - FREE_ARGS; + FREE_ARGS_FROM_I; rb_raise(rb_eDLTypeError, "unknown type '%c' of the return value.", @@ -923,9 +932,10 @@ rb_dlsym_call(int argc, VALUE argv[], VA }); dlfree((void*)ANY2S(args[i])); + ANY2S(args[i]) = 0; break; default: { char c = dtypes[i]; - FREE_ARGS; + FREE_ARGS_FROM_I; rb_raise(rb_eRuntimeError, "unknown argument type '%c'", i, c); } @@ -943,4 +953,5 @@ rb_dlsym_call(int argc, VALUE argv[], VA #undef FREE_ARGS +#undef FREE_ARGS_FROM_I return rb_assoc_new(val,dvals); }
-- Nobu Nakada