Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

XS DESTROY not invoked

by CarlosV (Novice)
on Sep 24, 2012 at 09:01 UTC ( [id://995317]=perlquestion: print w/replies, xml ) Need Help??

CarlosV has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

Debugging some memory leaks in a code with XS I have been reading perldoc perlxs guide to use DESTROY for freeing objects that get out of scope in perl. However my DESTROY function is never invoked and I can not understand why.

In the XS code there is a function "_new_from_der" that allocates memory and return it as a object "OpenCA_OpenSSL_CRL":

###################################################################### +### MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL OpenCA_OpenSSL_CRL _new_from_der(SV * sv)

This object is typemapped in what I understand is substitution of "_" for "::"

Typemap is:

OpenCA_OpenSSL_CRL T_PTROBJ_SPECIAL INPUT T_PTROBJ_SPECIAL if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt +}\")) { IV tmp = SvIV((SV*)SvRV($arg)); $var = INT2PTR($type,tmp); } else croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/:: +/g;\$ntt}\") OUTPUT T_PTROBJ_SPECIAL sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\", (void*)$var);

And typedef:

typedef X509_CRL * OpenCA_OpenSSL_CRL;

So, following the perlxs doc I inserted this DESTROY:

###################################################################### +### MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL +Ptr PREFIX = some_ void some_DESTROY(crl) OpenCA_OpenSSL_CRL crl CODE: fprintf(stderr, "DESTROY\n"); X509_CRL_free(crl);

But the DESTROY function is never invoked.

The main perl invocation is like this:

sub test { my $crl; $crl = OpenCA::OpenSSL::CRL::_new_from_der ($keys->{DATA}); }

I also tried using PACKAGE = OpenCA_OpenSSL_CRLPtr with no luck.

What I am doing wrong?

Regards,
Carlos Velasco

Replies are listed 'Best First'.
Re: XS DESTROY not invoked
by tobyink (Canon) on Sep 24, 2012 at 09:17 UTC

    Do you have a link to your full source code?

    Also, is $crl definitely a blessed reference in the expected package? (Check with Scalar::Util::blessed.)

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: XS DESTROY not invoked
by syphilis (Archbishop) on Sep 24, 2012 at 09:19 UTC
    But the DESTROY function is never invoked.

    DESTROY will only be (automatically) called on objects that have beem blessed into package OpenCA::OpenSSL::CRL.
    Do you have such objects ?

    Cheers,
    Rob
Re: XS DESTROY not invoked
by CarlosV (Novice) on Sep 24, 2012 at 09:32 UTC

    Wow, replying to myself. After reading a doc called "XS Mechanics" I did a last try, and this worked:

    ###################################################################### +### MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL void DESTROY(crl) OpenCA_OpenSSL_CRL crl CODE: fprintf(stderr, "DESTROY\n"); X509_CRL_free(crl);

    I am not 100% sure why this works, but as I read in the XS Mechanics, it seems that Ptr is only used/converted when a * is in the object, and as this is not the case, we don't need the Ptr at all, so the DESTROY can be in the OpenCA::OpenSSL::CRL package directly

    Sigh... I have been all weekend fighting with this, and never tried this :(

      I am not 100% sure why this work

      Neither are we , because we couldn't try this code :)

      Looks like all you did was remove prefix , and use a different package -- that could explain it (being in the wrong package)

Re: XS DESTROY not invoked
by Anonymous Monk on Sep 24, 2012 at 09:16 UTC

    Maybe whatever type of object you have, it is not blessed in the right package?

    Its easy to find out what you have by using plain print

    Also, tye says : don't do in XS what you can do in perl

    That might translate to

    sub OpenCA::OpenSSL::CRL::new { my $blah = OpenCA::OpenSSL::CRL::_new_from_der(@_); bless $blah, 'OpenCA::OpenSSL::CRL'; } sub OpenCA::OpenSSL::CRL::DESTROY { OpenCA::OpenSSL::CRL::X509_CRL_free(@_); }
Re: XS DESTROY not invoked
by bulk88 (Priest) on Sep 24, 2012 at 15:57 UTC
    If your are using C++ ignore half of what I said below.
    MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL OpenCA_OpenSSL_CRL _new_from_der(SV * sv)
    That is not valid XS code (maybe it now is in 2012), the types (SV *) go on the next inline in an explicity or implicity INPUT: section. Also _new_from_der will be called OpenCA::OpenSSL::CRL::_new_from_der in Perl. You also didn't show the body of _new_from_der so who knows if that works.
    MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL +Ptr PREFIX = some_
    MODULE = OpenCA::OpenSSL PACKAGE = OpenCA::OpenSSL::CRL
    2 different packages. Do a
    use Data::Dumper; use OpenCA::YourModule; print Dumper(\%OpenCA::OpenSSL::CRL::);
    to see what subs actually were registered in what packages. You can also look at end of the .c file generated during the compiling process for the "XS_EXTERNAL(boot_RootName__SecondName)" function and look at the newXS()s yourself. Also get very familiar with a step through C debugger and having your C compiler generate debugging symbols. You also will probably want to compile an -Od DEBUGGING perl for yourself too.

    edit:code sample fixed

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://995317]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-19 09:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found