--- Steve Hay <[EMAIL PROTECTED]> wrote:

> Why does the following XS code leak?
> 
> #include "EXTERN.h"
> #include "perl.h"
> #include "XSUB.h"
> 
> typedef struct {
>   char *buf;
> } Foo;
> 
> Foo *FooAlloc(pTHX) {
>   Foo *foo;
>   New(0, foo, 1, Foo);
>   New(0, foo->buf, 1024, char);
>   return foo;
> }
> 
> void FooFree(pTHX_ Foo *foo) {
>   Safefree(foo->buf);
>   //Safefree(foo);
> }
> 
> MODULE = Foo  PACKAGE = Foo       
> 
> void
> foo()
> PPCODE:
> {
>   SV *sv;
>   Foo *foo;
>   sv = NEWSV(0, 0);
>   foo = FooAlloc(aTHX);
>   sv_usepvn(sv, (char *)foo, sizeof *foo);
>   SvPOK_only(sv);
>   SvREADONLY_on(sv);
>   FooFree(aTHX_ foo);
>   SvREFCNT_dec(sv);
> }
> 
> The Safefree(foo) is commented out in FooFree() because I believe
> that sv_usepvn() has reallo()'ed foo and will free() it for me 
> when sv's refcount becomes 0.  I tried uncommenting the Safefree 
>(foo) to see if it made any difference, but it still leaks.
> 
> The leak is easily seen just by building a Foo module out of the
> above and running
> 
>     perl -Mblib -MFoo -e "<STDIN>; for (1 ..10000) { Foo::foo() }
> <STDIN>;"
> 
> If I comment-out the sv_usepvn() call, and accordingly restore the 
> Safefree(foo) once more, then the XSUB doesn't leak.
> 

Are you sure this line it right?

    sv_usepvn(sv, (char *)foo, sizeof *foo);

I get 4 for "sizeof *foo" on solaris, which is not nearly 
as much as the 1024 chars malloc'ed for buf.

I have a feeling that a different (probably smaller) size 
is being passed to realloc(), which leaves a chunk of memory 
out there that is probably not freed after SvREFCNT_dec.  
The man page for realloc hints at this (if the size is 0), 
but the whole thing is very subtle.


Just guessing ... I've never used sv_usepvn nor realloc for 
that matter, so I could be totally wrong.


Marc








__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Reply via email to